2

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(); }); 

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?

0

1 Answer 1

9

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.

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.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.