锁定语句中不允许使用C#(.NET Async CTP)中的await关键字.
来自MSDN:
await表达式不能用于同步函数,查询表达式,异常处理语句的catch或finally块,lock语句块或不安全上下文中.
我认为编译器团队出于某种原因要么难以实施,要么难以实现.
我尝试使用using语句:
class Async
{
public static async Task<IDisposable> Lock(object obj)
{
while (!Monitor.TryEnter(obj))
await TaskEx.Yield();
return new ExitDisposable(obj);
}
private class ExitDisposable : IDisposable
{
private readonly object obj;
public ExitDisposable(object obj) { this.obj = obj; }
public void Dispose() { Monitor.Exit(this.obj); }
}
}
// example usage
using (await Async.Lock(padlock))
{
await SomethingAsync();
}
Run Code Online (Sandbox Code Playgroud)
但是这不能按预期工作.在ExitDisposable.Dispose中对Monitor.Exit的调用似乎无限期地(大部分时间)阻塞,导致死锁,因为其他线程试图获取锁.我怀疑我的工作不可靠以及锁定语句中不允许等待语句的原因在某种程度上是相关的.
有谁知道为什么在锁定声明的正文中不允许等待?
我正在尝试将我的一些旧项目从TPLThreadPool和独立移动Thread到 TPL Task,因为它支持一些非常方便的功能,例如延续 with Task.ContinueWith(以及从 C# 5 with async\await)、更好的取消、异常捕获等。我很想在我的项目中使用它们。但是我已经看到了潜在的问题,主要是同步问题。
我写了一些代码来显示生产者/消费者问题,使用经典的独立Thread:
class ThreadSynchronizationTest
{
private int CurrentNumber { get; set; }
private object Synchro { get; set; }
private Queue<int> WaitingNumbers { get; set; }
public void TestSynchronization()
{
Synchro = new object();
WaitingNumbers = new Queue<int>();
var producerThread = new Thread(RunProducer);
var consumerThread = new Thread(RunConsumer);
producerThread.Start();
consumerThread.Start();
producerThread.Join();
consumerThread.Join();
}
private int ProduceNumber()
{
CurrentNumber++;
// Long running method. Sleeping …Run Code Online (Sandbox Code Playgroud) .net c# multithreading synchronization task-parallel-library