如何等待task.run

AjS*_*AjS 2 .net c# task-parallel-library async-await windows-store-apps

我正在写一个Windows商店应用程序,需要一些Task.Run方法的帮助.我正在调用服务从服务中检索数据; 因为我想在互联网断开时取消任务我正在通过CancellationToken

await Task.Run(async () => await Download1(), cts.Token); 
Run Code Online (Sandbox Code Playgroud)

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

await Task.Run(async () => await Download2(), cts.Token); 
Run Code Online (Sandbox Code Playgroud)

问题是上面的任务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;
                             }
                         });

        }
Run Code Online (Sandbox Code Playgroud)

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();
                            });

            }
        }
Run Code Online (Sandbox Code Playgroud)

i3a*_*non 5

你用的CoreDispatcher.RunAsync是接受的DispatchedHandler.DispatchedHandler有这个签名:

public delegate void DispatchedHandler()
Run Code Online (Sandbox Code Playgroud)

因此,当你传入一个asynclambda时,它最终会成为async void.这使得无法await返回任何任务.这意味着awaitlambda 中的所有内容将同时在不同的线程上运行.

您不应该将async委托传递给该方法.


作为旁注,传递a CancellationToken不会启用自动停止操作.它只能在启动之前停止操作,或者如果您正在操作中的某个位置观察令牌.

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

await Download1Async(cts.Token);
Run Code Online (Sandbox Code Playgroud)


Mat*_*int 5

你能顺序打电话给他们吗?

await Task.Run(async () =>
{
    await Download1();
    await Download2();
}); 
Run Code Online (Sandbox Code Playgroud)

您可能甚至不需要Task.Run,除非您从UI线程调用.如果您已经在后台线程,请尝试:

await Download1();
await Download2();
Run Code Online (Sandbox Code Playgroud)

当然,您的取消令牌可能应该以任何方式传递到下载功能.