我正在写一个程序,从一个网站下载游戏作为压缩档案,并提取他们。由于所有游戏在提取之前都被下载到相同的位置,所以当两个下载同时进行时,我使用Mutex来防止竞争条件。问题是,我被抛出了一个System.ApplicationException,上面写着:“对象同步方法是从一个不同步的代码块调用的。”我所看到的一切都表明,这是由于将Mutex从不拥有它的线程中释放出来造成的。但是,我的代码在同一个线程中等待和释放Mutex。
await Task.Run(async () =>
{
mutex.WaitOne();
await DownloadGameAsync(ug, nvm);
await ExtractGameAsync(ug, nvm);
nvm.Action = "Done";
mutex.ReleaseMutex();
});但是,如果我在mutex.ReleaseMutex()行上放置了一个断点,并且跨行,它不会导致抛出异常,移除断点并运行通常会导致每次执行时出现异常。
我应该以不同的方式(信号量)来处理这个问题,还是我使用异步/等待会导致这个问题?
发布于 2013-11-20 17:06:14
在一般情况下,不能使用线程仿射同步原语(例如Mutex)和async。具体来说,await之后的代码不能保证运行在与获取互斥线程相同的线程上。
我建议使用SemaphoreSlim及其WaitAsync方法。SemaphoreSlim是唯一保证与await正确工作的BCL同步原语。如果您需要更复杂的同步原语,Stephen编写了一个关于我扩展并包含在我的series of blog posts中的主题的AsyncEx library。
https://stackoverflow.com/questions/20101952
复制相似问题