Task.Run代码没有执行

时间:2014-05-12 03:05:09

标签: .net task async-await c#-5.0

有人可以解释为什么SecondTask和load事件没有根据此代码更新UI吗?

    public Task First()
{
    return Task.Run(
       () =>
        {

            Task.Delay(4000);
            Dispatcher.Invoke(() =>
            {
                Title = "From First()";
            });
        });
}
public Task Second()
{
    return Task.Run(
         () =>
        {
            Task.Delay(5000);
            Dispatcher.Invoke(() =>
            {
                Title = "From Second()";
            });
            Task.WaitAny(First());
        });

}
    private  void ParentWindow_Loaded(object sender, RoutedEventArgs e)
    {
         Second();
        Title = "From Event";
    }

当我运行此代码时,由于调用First(),只有表单的标题只会更改一次。 没有其他任何执行(至少从我能看到的,我可以看到达到了断点)。 我还尝试使用Task.WhenAny(First());代替Task.WaitAny(First());

2 个答案:

答案 0 :(得分:3)

问题是没有等待Task.DelayTask.Delay是异步睡眠,因此它会立即返回,如果您想在延迟后实际继续执行,则需要await它。

因此,方法Second()中发生的是lambda表达式在后台线程上执行。调用Task.Delay(5000)时,调用会立即返回,因为未等待,Title将设置为From Second()

public Task Second()
{
    return Task.Run(
         () =>
        {
            Task.Delay(5000); // need to await here
            Dispatcher.Invoke(() =>
            {
                Title = "From Second()";
            });
            Task.WaitAny(First());
        });

}
然后调用

First(),因为还没有等待Task.Delay(4000),它会立即将Title设置为From First()。因此,最终结果是您只会看到From First()

public Task First()
{
    return Task.Run(
       () =>
        {

            Task.Delay(4000); // need to await here
            Dispatcher.Invoke(() =>
            {
                Title = "From First()";
            });
        });
}

您可能还希望await在事件处理程序中调用Second(),除非您打算先将标题设置为From Event,然后使用{{1}的结果覆盖它}}

Second()

答案 1 :(得分:1)

首先,您需要了解有关任务的编程。请阅读my curation上的文章。

执行任务,你不要等他们完成任务。

async-await可以轻松完成异步工作,因此,您不应该将UI与非UI代码混合使用。试试这个:

public async Task FirstAsync()
{
    await Task.Delay(4000);
    Title = "From First()";
}

public async Task SecondAsync()
{
    await Task.Delay(5000);
    Title = "From Second()";
    await FirstAsync();
}

private async void ParentWindow_Loaded(object sender, RoutedEventArgs e)
{
    await SecondAsync();
    Title = "From Event";
}

这可以做你想要的,而且代码更清晰。

相关问题