【发布时间】:2020-11-17 21:20:48
【问题描述】:
我正在使用此类来防止两个应用程序(一个 Windows 应用程序和一个在同一操作系统上运行的 Web 应用程序)同时使用共享文件。但我收到错误“对象同步方法是从未同步的代码块中调用的。”
class SharedMutex : IDisposable
{
readonly Mutex mutex;
/// <summary>
/// This function will wait if other thread has owned the mutex
/// </summary>
/// <param name="name"></param>
public SharedMutex(string name)
{
bool m = Mutex.TryOpenExisting(name, out mutex);
if (m)
{
mutex.WaitOne();
}
else
{
mutex = new Mutex(true, name);
}
}
public const string Logs = @"Global\Logs";
public void Dispose()
{
mutex.ReleaseMutex();
mutex.Dispose();
}
}
这就是我使用这个类的方式
using (new SharedMutex(SharedMutex.Logs))
{
///access the shared file
}
这个类存在于两个项目中。
注意:我不是在寻找访问文件问题的解决方案,我需要知道为什么我的代码有问题。因为我也想将此代码用于其他目的。 谢谢。
【问题讨论】:
-
您的“访问共享文件”是否包含
await? -
"互斥锁具有线程亲和性,互斥锁的所有者是线程。获取它的线程也必须是调用 ReleaseMutex() 的线程。这就是您的代码炸弹的原因." - stackoverflow.com/a/9017728/43846
-
这个错误意味着你试图从另一个线程释放互斥锁,而不是一个拥有所有权的线程。没有minimal reproducible example,很难添加更多内容。
-
@Sinatr 应该重新打开吗?
-
我认为问题是
TryOpenExisting之间的竞争条件,它返回false并试图创建具有else所有权的互斥锁。你可能不会成功。您没有按照重复的答案处理这种情况。
标签: c# multithreading thread-safety mutex