让Task.Delay在调用线程上继续

时间:2015-12-14 06:27:04

标签: c# task-parallel-library

考虑这种方法:

//Called on a known thread
    public async void ThreadSleep()
    {
     while(itemsInQueue)
      {
        //This call is currently on Thread X
        await Task.Delay(5000);
       //This needs to be on the thread that the method was called on
        DoSomeProcessing();
       }
    }

我假设Task.Delay在不同的线程上执行异步并在同一个线程上恢复。这对我来说不是很明显。如何让方法在Thread X上继续?

PS:ThreadSleep方法在非UI线程上执行

编辑:1)为简单起见,添加了W.Brian的代码示例。

2)是的,这个例子就是......一个例子。

3)Thread.Delay的目的只是在处理之间增加一些延迟。

2 个答案:

答案 0 :(得分:4)

您需要创建自己的同步上下文(就像UI线程一样)。

There's a pretty good article on MSDN that helps to understand the problem and how to create a solution.

介意我问你为什么要继续使用同一个帖子? 通常它不应该在使用新线程时创建和发布,因为保留了上下文。

如果你需要在更深层次的调用之间保留某种上下文(就像你使用ThreadLocal那样),我建议你使用新的AsyncLocal来实现这个目标。 它确保即使线程发生更改,不可变对象仍保留在异步上下文中(请参阅:How do the semantics of AsyncLocal differ from the logical call context?)。

答案 1 :(得分:0)

await Task.Delay(5000).ConfigureAwait(true);

调用ConfigureAwait(true)应该有效,因为它确保与原始线程相同的上下文,即使线程发生了变化。这假设未使用ThreadLocal<T>,在这种情况下,async / await通常会导致问题,如果您无法更改其余代码,则Thread.Sleep可能是首选。