名为Mutex等待

Rom*_*asz 15 c# multithreading asynchronous async-await

因此我不能使用线程仿射锁async- 如何在运行多个进程时保护我的资源?

例如,我有两个使用以下任务的进程:

 public async Task<bool> MutexWithAsync()
 {
     using (Mutex myMutex = new Mutex(false, "My mutex Name"))
     {
         try
         {
             myMutex.WaitOne();
             await DoSomething();
             return true;
         }
         catch { return false; }
         finally { myMutex.ReleaseMutex(); }
     }
 }
Run Code Online (Sandbox Code Playgroud)

如果由Mutex保护的moethod是同步的,那么上面的代码将起作用,但async我会得到:

从不同步的代码块调用对象同步方法.

Named Mutex对异步代码没用吗?

usr*_*usr 11

您必须确保在某个线程上一致地访问互斥锁.你可以通过多种方式做到这一点:

  1. 不要在持有互斥锁的关键部分中使用等待
  2. TaskScheduler只有一个线程的情况下调用互斥锁调用

这看起来像这样:

await Task.Factory.StartNew(() => mutex.WaitOne(), myCustomTaskScheduler);
Run Code Online (Sandbox Code Playgroud)

或者,您使用同步代码并将所有内容移动到线程池.如果您只能访问异步版本DoSomething,请考虑只调用Task.Wait其结果.你在这里会遭受轻微的低效率.可能还不错.

  • 是的,但捕获的上下文可能意味着"任何线程池线程".鉴于我所拥有的信息,我认为所有3个提议的解决方案都适合您.如果您需要其他信息,请与我们联系. (2认同)

Ser*_*yev 5

我在异步方法中使用命名互斥锁来控制只有一个进程调用它。另一个进程检查命名互斥体,如果不能创建新的命名互斥体则退出。

我可以在异步方法中使用命名互斥锁,因为操作系统保证/控制操作系统中命名对象的一个​​实例。另外,我不使用应该在线程上调用的 WaitOne/Release。

public async Task<bool> MutexWithAsync()
{
    // Create OS-wide named object. (It will not use WaitOne/Release)
    using (Mutex myMutex = new Mutex(false, "My mutex Name", out var owned))
    {
        if (owned)
        {
            // New named-object was created. We own it.
            try
            {
                await DoSomething();
                return true;
            }
            catch
            {
                return false;
            }
        }
        else
        {
            // The mutex was created by another process.
            // Exit this instance of process.
        }
    }
}
Run Code Online (Sandbox Code Playgroud)