gpt4 book ai didi

c# - 为什么我的代码在同步时不能正常工作?

转载 作者:行者123 更新时间:2023-12-03 12:58:27 26 4
gpt4 key购买 nike

我正在使用此类来防止两个应用程序(一个 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
}
这个类存在于两个项目中。
注意:我不是在寻找访问文件问题的解决方案,我需要知道为什么我的代码有问题。因为我也想将此代码用于其他目的。
谢谢你。

最佳答案

我认为这可能是由竞争条件引起的(正如/u/Sinatr 在问题评论中所建议的那样)。
以下代码重现了该问题:

using System;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApp1
{
class Program
{
static void Main()
{
var t1 = Task.Run(func1);
var t2 = Task.Run(func2);

Task.WaitAll(t1, t2);

Console.WriteLine("Done. Press <ENTER>");
Console.ReadLine();
}

static void func1()
{
using (new SharedMutex("test"))
{
Thread.Sleep(2000);
}
}

static void func2()
{
using (new SharedMutex("test"))
{
Thread.Sleep(1000);
}
}
}

class SharedMutex : IDisposable
{
readonly Mutex mutex;

public SharedMutex(string name)
{
bool m = Mutex.TryOpenExisting(name, out mutex);

if (m)
{
mutex.WaitOne();
}
else
{
Thread.Sleep(10); // Simulate a short delay.
mutex = new Mutex(true, name);
}
}

public void Dispose()
{
mutex.ReleaseMutex();
mutex.Dispose();
}
}
}
注意短暂的延迟 Thread.Sleep(10)这足以在我的系统上引发异常,运行调试版本。可能必须增加延迟以在其他系统上引发异常。
如果这确实是问题,这是解决方法:
class SharedMutex : IDisposable
{
readonly Mutex mutex;

public SharedMutex(string name)
{
mutex = new Mutex(false, name);
mutex.WaitOne();
}

public void Dispose()
{
mutex.ReleaseMutex();
mutex.Dispose();
}
}
你并不关心它是否是新创建的。 Mutex 构造函数会为您处理这些问题。
即使这不是问题,我仍然认为您应该使用上面的实现,因为它没有潜在的竞争条件。
the documentation for the constructor Mutex(bool, string) 状态:

If name is not null and initiallyOwned is true, the calling threadowns the mutex only if the named system mutex was created as a resultof this call. Since there is no mechanism for determining whether thenamed system mutex was created, it is better to specify false forinitiallyOwned when calling this constructor overload.

关于c# - 为什么我的代码在同步时不能正常工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63134047/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com