C#中的互斥量-来自未同步代码块的同步 [英] Mutex in C# - Synchronization from Unsynchronized Block of Code

查看:182
本文介绍了C#中的互斥量-来自未同步代码块的同步的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个程序,该程序从网站下载游戏作为zip存档并将其提取.由于所有游戏在提取前都会下载到相同位置,因此我使用Mutex来防止在同时进行两次下载时出现比赛情况.问题是我得到System.ApplicationException的提示:对象同步方法是从未同步的代码块中调用的."我所看到的一切都说这是由于从不拥有Mutex的线程中释放Mutex引起的.但是,我的代码在同一线程中等待并释放Mutex.

I am writing a progam which downloads games from a website as zip archives and extracts them. Since all games are downloaded to the same location before being extracted I am using a Mutex to prevent race conditions when two downloads are going on at the same time. The issue is that I am getting a System.ApplicationException thrown saying: "Object synchronization method was called from an unsynchronized block of code." Everything I have looked at says that this is caused by freeing a Mutex from a thread that does not own it. However, my code Wait's and Releases the Mutex in the same thread.

await Task.Run(async () =>
{
   mutex.WaitOne();
   await DownloadGameAsync(ug, nvm);
   await ExtractGameAsync(ug, nvm);
   nvm.Action = "Done";
   mutex.ReleaseMutex();
});

如果我在mutex.ReleaseMutex();行上放置断点并跨过该行不会导致引发异常,但是,删除断点并正常运行会在每次执行时导致异常.

If I place a breakpoint on the line mutex.ReleaseMutex(); and step over the line it does not cause the exception to be thrown however, removing the breakpoint and running normally causes an exception with every execution.

我应该采用不同的方式(信号量)还是使用异步/等待引起问题?

Should I be approaching this differently (Semaphores) or is my use of async/await causing the issue?

推荐答案

通常,不能将线程仿射同步原语(例如, Mutex )与 async 一起使用案件.具体来说, await 之后的代码不能保证在与获取互斥锁的线程相同的线程上运行.

You cannot use thread-affine synchronization primitives (e.g., a Mutex) with async in the general case. Specifically, your code after the await is not guaranteed to run on the same thread as the thread that acquired the mutex.

我建议使用 SemaphoreSlim 及其 WaitAsync 方法. SemaphoreSlim 是唯一可以保证与 await 一起正常工作的BCL同步原语.如果您需要更复杂的同步原语,Stephen Toub撰写了一系列博客文章关于我扩展并包含在我的 AsyncEx库中的主题.

I recommend using SemaphoreSlim and its WaitAsync method. SemaphoreSlim is the only BCL synchronization primitive that is guaranteed to work correctly with await. If you need more complex synchronization primitives, Stephen Toub wrote a series of blog posts on the subject that I extended and included in my AsyncEx library.

这篇关于C#中的互斥量-来自未同步代码块的同步的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆