等待任务不按我期望的方式行事

时间:2016-05-06 19:04:40

标签: c# .net async-await win-universal-app

我的代码路径不符合我的预期;我可能有一个错误,但我怀疑它有可能等待我误解的任务。以下代码的目的是导航到第二个屏幕,然后根据超时,再次导航并尝试共享一些内容:

AdvertHelper adHelper = new AdvertHelper();

Task nav = new Task(async () =>
{
    await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () =>
    {
        System.Diagnostics.Debug.WriteLine("Call Navigate to MainPageViewModel");
        Navigation.Navigate<MainPageViewModel>();

        saved = await SaveVideo();
        System.Diagnostics.Debug.WriteLine("After SaveVideo()");
    });
});
adHelper.DisplayAdvert(this, nav);

System.Diagnostics.Debug.WriteLine($"Before await nav (saved: {saved})");
await nav;
System.Diagnostics.Debug.WriteLine($"After await nav (saved: {saved})");

DisplayAdvert看起来像这样:

    public void DisplayAdvert(BaseViewModel sourceVM, Task afterAdvert)
    {                        
        _afterShow = afterAdvert;
        _tmr = new DispatcherTimer();
        _tmr.Tick += _tmr_Tick;
        _tmr.Interval = new TimeSpan(0, 0, 2);
        _tmr.Start();

        Navigation.Navigate<AdvertViewModel>();
    }

和超时:

    private void _tmr_Tick(object sender, object e)
    {            
        _afterShow.Start();
        _tmr.Stop();
    }

所以,我的理解是我创建了一个导航到MainPageViewModel的任务,然后尝试保存视频(出于此目的,想象一下SaveVideo()只是在异步函数中返回true几秒钟后。

从调试开始:

Before await nav (saved: False)
Call Navigate to MainPageViewModel
SaveVideo() Called
After await nav (saved: False)
SaveVideo() Return true
After SaveVideo()

因此,如果我正确读取此代码,代码不会等待任务nav(因此也就是SaveVide()),但是仍在继续,因此无法获得SaveVideo()的结果正确的时间。

1 个答案:

答案 0 :(得分:4)

您看到的核心问题是Task构造函数无法理解async个委托。 You should never, ever use the Task constructor; as I describe on my blog, there are no use cases for it. Ever.

  

以下代码的目的是导航到第二个屏幕,然后根据超时,再次导航并尝试共享一些内容

那为什么不是这样的呢?

Navigation.Navigate<AdvertViewModel>();
await Task.Delay(2);
Navigation.Navigate<MainPageViewModel>();
saved = await SaveVideo();