2013-10-19 50 views
7

我想了解async/await关键字是如何工作的。我有一个WPF窗口上的textblock绑定到一个TextBlockContent字符串属性和一个按钮触发点击ChangeText()。当我指定ConfigureAwait(false)时,为什么仍然在主线程中?

这里是我的代码:

public async void ChangeText() 
{ 
    string mystring = await TestAsync(); 
    this.TextBlockContent= mystring; 
} 

private async Task<string> TestAsync() 
{ 
    var mystring = await GetSomeString().ConfigureAwait(false); 
    mystring = mystring + "defg"; 
    return mystring; 
} 

private Task<string> GetSomeString() 
{ 
    return Task.Run(() => 
    { 
     return "abc"; 
    }); 
} 

从我阅读,我明白了ConfigureAwait设置为false,让我指定我不想保存当前上下文的任务的“休息”需要在await关键字后执行。

调试后我意识到,当我有这段代码时,有时代码在主线程后面运行:等待GetSomeString()。ConfigureAwait(false);而我特别添加了配置等待。

我原以为它总是运行在它进入任务之前的那个不同的线程上。

有人可以帮我理解为什么吗?

非常感谢您

+0

我2美分:如果你真的想确保你继续在'await'后的新线程,你可以用[自定义awaiter](http://stackoverflow.com/questions/18779393/the-lack-的,非捕获任务屈服的力量,我使用的任务 - 运行 - 为什么 - 跟踪这一点)。不过,这被认为是不好的做法。 – Noseratio

回答

12

它很可能是你正在运行的任务完成立即 - 这意味着await甚至不需要安排的延续。一个async方法只在需要时调度延续;如果你等待已经完成的东西,它会继续 - 在同一个线程中。

ConfigureAwait暗示你不需要需要继续在相同的上下文中;不要求您在相同的上下文中继续使用不得保留

如果您将任务更改为未立即完成的任务 - 例如请致电Thread.Sleep(1000)(当然,您通常不会这样做),我希望您看到行为发生变化。

有可能我错过了其他的东西,而且这个不是问题的原因,但至少应该首先尝试。

+0

你的意思是'Task.Delay',而不是'Thread.Sleep()'你呢? –

+0

好像它是。我知道调度器不会安排一个任务,如果已经完成像Task.FromResult(...)但我不知道如果执行几乎是“即时”,它会认为它直接完成。感谢您的解释 ! –

+1

@Alexei:不,我的意思是Thread.Sleep。关键是要创建一个快速完成的任务。睡觉是一个简单的方法。 –

相关问题