c# - Task.WhenAny 只抓取解决最快的任务
问题描述
我有两个异步方法都返回一个列表。他们都以不同的方式搜索记录,我需要他们都并行运行,我只关心首先完成的任务。如果可能,应取消另一个。
我想我应该使用 Task.WhenAny 但似乎没有得到正确的实现。下面的 GoAsync 实现不返回任何记录,它在 await Task.WhenAny(taskList) 行跳出例程(无错误)。我没有得到结果,等等。我怎样才能得到结果?我这样做对吗?
public static async void GoAsync(SearchContract search, CancellationToken cancellationToken = default(CancellationToken))
{
var taskList = new List<Task>();
taskList.Add(new Task(async () => await SearchRoutine1Async(search, cancellationToken)));
taskList.Add(new Task(async () => await SearchRoutine2Async( search, cancellationToken)));
Task completedTask = await Task.WhenAny(taskList);
}
异步例程是这样的:
public static async Task<List<SearchModel>> SearchRoutine1Async( SearchContract search, CancellationToken cancellationToken = default(CancellationToken))
{
using (DBContext db = new DBContext)
{
var searchModels= await db.SearchModel
.Where(sm => sm.subKey1 = search.subKey1)
.ToListAsync(cancellationToken)
;
return searchModels;
}
}
当我尝试单独运行这些任务时,例如这样做:它工作正常。
var callTask = Task.Run(() => SearchRoutine1Async(search));
callTask.Wait();
var list1 = callTask.Result;
var callTask2 = Task.Run(() => SearchRoutine2Async(search));
callTask2.Wait();
var list2 = callTask.Result;
[更新]:我已将我的 GoAsync 更改为:根据以下答案之一:(但它仍然无法正常工作)
public static async Task<List<SearchModel>> GoAsync(SearchContract search, CancellationToken cancellationToken = default(CancellationToken))
{
var taskList = new List<Task<List<SearchModel>>>
{
SearchRoutine1Async(search, cancellationToken),
SearchRoutine2Async(search, cancellationToken)
};
Task<List<SearchModel>> completedTask = await Task.WhenAny(taskList);
return completedTask.Result;
}
我从 SYNCHRONOUS 例程中调用例程,如下所示:
var result = GoAsync(search);
请注意,我深陷于需要并行运行这些任务以获得竞争结果的例程中。该例程作为 private static void DoVariousCalucualtions() {} 的签名
解决方案
您不需要创建new Task
,异步方法将返回一个任务。
public static async Task GoAsync(
SearchContract search,
CancellationToken cancellationToken = default(CancellationToken))
{
var taskList = new List<Task<List<SearchModel>>>
{
SearchRoutine1Async(search, cancellationToken),
SearchRoutine2Async( search, cancellationToken)
};
Task<List<SearchModel>> completedTask = await Task.WhenAny(taskList);
// use competedTask.Result here (safe as you know task is completed)
}
问题更新后:
要获得结果,您需要等待功能完成。
var result = await GoAsync();
但是您提到此调用位于带有void
签名的同步函数的深处,并且您没有使用 ASP.Net Core。这意味着您需要从控制器操作开始使整个“方法管道”异步。如果你会使用GoAsync().Result;
你最终会陷入僵局,你已经经历过的行为......
推荐阅读
- java - Android 和 CherryPy
- powershell - Powershell Compare-Object 比较不在组列表中的广告用户
- android - 如何导航到半片段?(导航架构组件)
- makefile - 运行多个版本的测试并在 Makefile 中收集返回值
- c# - 使用 C# 和 StorageManagementClient/ComputeManagementClient 将 Azure 磁盘附加到 VM
- .net - Regular expression with full match only
- angular - UI-Router 重定向到不工作的孩子
- typescript - Typescript 没有从 d.ts 文件中获取现有 js 文件的任何类型信息
- javascript - Regex - matching brazilian phone numbers
- clarity - How to perform the calculation details for field ETC(Cost) in Clarity PPM?