gpt4 book ai didi

c# - Mutex/Monitor 不适用于 C# 线程同步

转载 作者:行者123 更新时间:2023-11-30 13:58:48 25 4
gpt4 key购买 nike

我试图只允许一个 Thread 从一个 object 访问一个非静态方法。我并没有真正创建线程,而是使用任务。我试图将该方法锁定为一种用法,但它不起作用,我首先尝试使用静态 Mutex 对象,然后使用非静态 Mutex 对象,但是即使使用简单的显示器也无法正常工作。

我的代码:

private async void LoadLinkPreview()
{
try
{
// TODO: FEHLERTRÄCHTIG!
Monitor.Enter(_loadLinkMonitor);
Debug.WriteLine(DateTime.Now + ": Entered LinkPreview");

// Code ...
// There are also "await" usages here, don't know if this matters
}
catch { }
finally
{
Monitor.Exit(_loadLinkMonitor);
Debug.WriteLine(DateTime.Now + ": Left LinkPreview");
}
}

这是控制台显示的内容:

3/12/2013 6:10:03 PM: Entered LinkPreview
3/12/2013 6:10:05 PM: Entered LinkPreview
3/12/2013 6:10:05 PM: Left LinkPreview
3/12/2013 6:10:06 PM: Left LinkPreview

当然,有时它会按需要的顺序工作,但我希望它始终有效。有人可以帮助我吗?

编辑:我意识到控制台显示可能是想要的行为,因为“左”WriteLine() 是在监视器退出之后,但我现在切换它们并且可以确认有绝对是两个线程同时工作!还有一个更明显的控制台结果:

3/12/2013 6:26:15 PM: Entered LinkPreview
3/12/2013 6:26:15 PM: Entered LinkPreview
2 had an error! // Every time the method is used I count up now, this confirms that the second
// time the method is called the error is produced, which would not happen if the monitor
// is working because I have an if statement right upfront ...
3/12/2013 6:26:17 PM: Left LinkPreview
3/12/2013 6:26:18 PM: Left LinkPreview

最佳答案

实际上有可能您的代码按预期工作,而您的问题只是与显示有关。

问题在这里:

 Monitor.Exit(_loadLinkMonitor);
Debug.WriteLine(DateTime.Now + ": Left LinkPreview");

您在退出监视器后写下时间戳。请记住,等待进入监视器的其他代码可以在调用 Exit 后立即开始执行。因此当前线程有可能调用 exit,然后在 Debug 调用之前,另一个线程可以 Enter 监视器并将其写在“Entered”行上。

如果将代码更改为:

 Debug.WriteLine(DateTime.Now + ": Left LinkPreview");
Monitor.Exit(_loadLinkMonitor);

然后它不会改变行为,但您将删除日志记录错误。如果它仍然不正常,那么您的代码中确实有问题。

附带说明,如果您有 async 方法,则应避免调用执行阻塞等待的方法,例如 Monitor.Enter。如果您使用 SemaphoreSlim,您可以使用它的 WaitAsync 方法来确保该方法不会阻塞。这看起来像这样:

private SemaphoreSlim semaphore = new SemaphoreSlim(1);
private async void LoadLinkPreview()
{
try
{
await semaphore.WaitAsync();
Debug.WriteLine(DateTime.Now + ": Entered LinkPreview");
await Task.Delay(2000);//placeholder for real work/IO
}
finally
{
Debug.WriteLine(DateTime.Now + ": Left LinkPreview");
semaphore.Release();
}
}

关于c# - Mutex/Monitor 不适用于 C# 线程同步,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15367841/

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