如何等待task.run

本文关键字:task run 等待 何等待 | 更新日期: 2023-09-27 17:50:37

我正在写一个windows商店应用程序,需要Task.Run方法的一些帮助。我正在调用服务从服务检索数据;因为我想在网络断开时取消任务我传递了CancellationToken

await Task.Run(async () => await Download1(), cts.Token); 

还有另一个下载方法,应该在上述任务完成后运行,所以我使用await。两个任务都写入相同的文件,所以我想确保它们不是并行运行的。

await Task.Run(async () => await Download2(), cts.Token); 

问题是上面的任务2在任务1没有完成的情况下启动,所以两个任务并行运行。我做错了什么?请建议。

Download1看起来像这样:-

 public async Task Download1()
        {
         await   Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal,
                         async () =>
                         {
                             Status = "Downloading!";
                             var ListSetupTasks = new List<SetupView>();
                             foreach (var setup in AllSetupTasks.Setup)
                             {
                                 ListSetupTasks.Add(new SetupViewModel(setup));
                             }
                             IEnumerable<Task> downloadTasksQuery = from setup in ListSetupTasks where setup.TaskType == TaskType.Web select _masterlistrepository.GetTask(setup, false, datetime, branch);
                             Task[] downloadTasks = downloadTasksQuery.ToArray();
                             await Task.WhenAll(downloadTasks);
                             IEnumerable<Task> FinalTasksQuery = from setup in ListSetupTasks where setup.TaskType == TaskType.Web select _masterlistrepository.GetTask(setup, false);
                             foreach (var task in FinalTasksQuery)
                             {
                                 await task;
                             }
                         });
        }

CancellationToken是这样使用的:-

async void NetworkChanged(object sender, NetworkConnectionStatusChangedEventArgs e)
        {
            if (e.Value == false && LoadingData == true)
            {
             await   Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal,
                            async () =>
                            {
                                await _alertmessageservice.ShowAsync("", "Network error. Please retry!");
                                cts.Cancel();
                            });
            }
        }

如何等待task.run

您使用接受DispatchedHandlerCoreDispatcher.RunAsyncDispatchedHandler有这样的签名:

public delegate void DispatchedHandler()

所以当你传入一个async,它最终会是async void。这使得await不可能,因为没有任务被返回。这意味着在lambdas中await之后的所有内容将并发地运行在不同的线程上。

你不应该把async委托传递给那个方法。


作为旁注,传递CancellationToken并不启用自动停止操作。它只能在操作开始之前停止,或者当您在操作中观察到令牌时。

所以,实际使用CancellationToken Download应该接受使用它,使Task.Run冗余:

await Download1Async(cts.Token);

可以按顺序调用它们吗?

await Task.Run(async () =>
{
    await Download1();
    await Download2();
}); 

你甚至可能不需要Task.Run,除非你是从一个UI线程调用。如果你已经在后台线程上,那么试试:

await Download1();
await Download2();

当然,您的取消令牌可能应该以任何一种方式传递到下载函数中。