有这样一段代码(取自 Schildt 并略有简化)。
using System;
using System.Threading;
class ThreadTest
{
object lk = new object();
public void Tick()
{
lock (lk)
{
for (int x = 0; x < 12; x++)
{
Console.WriteLine("tick");
Thread.Sleep(200);
Monitor.Pulse(lk);
Monitor.Wait(lk);
}
Monitor.PulseAll(lk);
}
}
public void Tock()
{
lock (lk)
{
for (int x = 0; x < 12; x++)
{
Console.WriteLine("tock");
Thread.Sleep(200);
Monitor.Pulse(lk);
Monitor.Wait(lk);
}
Monitor.PulseAll(lk);
}
}
}
class demo
{
static void Main()
{
ThreadTest thrTest = new ThreadTest();
Thread t1 = new Thread(thrTest.Tick); t1.Start();
Thread t2 = new Thread(thrTest.Tock); t2.Start();
}
}
此代码在不同线程中启动方法,并同步它们的工作,在控制台上显示 Tik 或 Tak。但我想,我怎样才能实现相同的功能,但使用asynс/await? 这是真的吗?
是的,你可以,虽然它有点复杂。
本文介绍了如何自己动手做的机制。但是最好不要重新发明轮子,而是使用现成的AsyncEx库。有了这个库的连接,你可以简单地写:
(两位作者都是公认的异步编程专家。Stephen Toub 是 Microsoft 的TPL开发人员之一,Stephen Cleary 是一本好书Concurrency in C# Cookbook的作者。)
关于具有执行顺序的特定代码 - 这可以更容易地完成。我曾经
AsyncBarrier从同一个Nito.AsyncEx.请注意,Schildt 的原始示例是不正确的。它用
Thread.Sleep它来“保证”有一个等待线程,这是一个严重的错误计算。从文档中Monitor.Pulse:然而,Schiltt 的著作却以草率着称。
澄清:不,席尔特的例子还是正确的,
Thread.Sleep它并没有起到决定性的作用。然而,来自 MSDN 的引用仍然有效,使用Wait/Pulse同步线程是危险的。