首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C#中的互斥-来自非同步代码块的同步

C#中的互斥-来自非同步代码块的同步
EN

Stack Overflow用户
提问于 2013-11-20 16:52:11
回答 1查看 2.1K关注 0票数 2

我正在写一个程序,从一个网站下载游戏作为压缩档案,并提取他们。由于所有游戏在提取之前都被下载到相同的位置,所以当两个下载同时进行时,我使用Mutex来防止竞争条件。问题是,我被抛出了一个System.ApplicationException,上面写着:“对象同步方法是从一个不同步的代码块调用的。”我所看到的一切都表明,这是由于将Mutex从不拥有它的线程中释放出来造成的。但是,我的代码在同一个线程中等待和释放Mutex。

代码语言:javascript
复制
await Task.Run(async () =>
{
   mutex.WaitOne();
   await DownloadGameAsync(ug, nvm);
   await ExtractGameAsync(ug, nvm);
   nvm.Action = "Done";
   mutex.ReleaseMutex();
});

但是,如果我在mutex.ReleaseMutex()行上放置了一个断点,并且跨行,它不会导致抛出异常,移除断点并运行通常会导致每次执行时出现异常。

我应该以不同的方式(信号量)来处理这个问题,还是我使用异步/等待会导致这个问题?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-11-20 17:06:14

在一般情况下,不能使用线程仿射同步原语(例如Mutex)和async。具体来说,await之后的代码不能保证运行在与获取互斥线程相同的线程上。

我建议使用SemaphoreSlim及其WaitAsync方法。SemaphoreSlim是唯一保证与await正确工作的BCL同步原语。如果您需要更复杂的同步原语,Stephen编写了一个关于我扩展并包含在我的series of blog posts中的主题的AsyncEx library

票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20101952

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档