【发布时间】:2018-11-28 07:14:52
【问题描述】:
我有两个异步方法都返回一个列表。他们都以不同的方式搜索记录,我需要他们都并行运行,我只关心首先完成的任务。如果可能,应取消另一个。
我认为我应该使用 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);
请注意,我深陷于例行程序中,我需要并行运行这些任务以获得竞争结果。那个例程作为一个签名 私有静态无效 DoVariousCalucualtions() {}
【问题讨论】:
-
将
completedTask转换为Task<List<SearchModel>>??为什么async void???? -
任务(仍然)不是线程并且异步不是并行的:wintellect.com/…code-maze.com/csharp-delegates
-
它在 await Task.WhenAny(taskList) 行跳出了例程(没有错误) 好吧,你让它异步了??????
-
@ta.speot.is ...好吧,如果我在那之后添加一行代码 await Task.WhenAny(taskList) 行...就像 var result = completedTask.Result 它永远不会到达那一行要么......它只是跳出常规。
-
@user1161137
async void GoAsync是一个错误,应该是async Task GoAsync()。async void仅适用于事件处理程序。async void方法无法等待,并且在应用程序或请求终止时可能仍在运行。如果您不希望它异步运行,请使用Task.WaitAny
标签: c# async-await task-parallel-library