gpt4 book ai didi

C# 线程同步监视器 + ResetEvent

转载 作者:太空宇宙 更新时间:2023-11-03 16:23:37 25 4
gpt4 key购买 nike

我已经编写了一个 DirectSoundWrapper,但我只能通过 MTA 线程访问接口(interface)。所以我创建了一个线程,它在后台工作并在队列中执行操作。我做过这样的事情:

private void MTAQueue()
{
lock (queueLockObj)
{
do
{
if (marshalThreadItems.Count > 0)
{
MarshalThreadItem item;
item = marshalThreadItems.Dequeue();
item.Action();
}
else
{
Monitor.Wait(queueLockObj);
}
} while (!disposing);
}
}

然后我执行这样的操作:

private void ExecuteMTAAction(Action action)
{
if (IsMTAThread)
action();
else
{
lock (queueLockObj)
{
MarshalThreadItem item = new MarshalThreadItem();
item.Action = action;
marshalThreadItems.Enqueue(item);

Monitor.Pulse(queueLockObj);
}
}
}

但现在我想等待完成调用的操作。所以我想使用 ManuelResetEvent:

private void ExecuteMTAAction(Action action)
{
if (IsMTAThread)
action();
else
{
lock (queueLockObj)
{
MarshalThreadItem item = new MarshalThreadItem();
item.Action = action;
item.waitHandle = new ManualResetEvent(false); //setup
marshalThreadItems.Enqueue(item);

Monitor.Pulse(queueLockObj); //here the pulse does not pulse my backgrond thread anymore
item.waitHandle.WaitOne(); //waiting
}
}
}

我的后台线程是这样编辑的:

item.Action();
item.waitHandle.Set();

问题是后台线程不再有脉冲,只是一直在等待 (Monitor.Wait(queueLockObj)),而调用操作的主线程在 manuelresetevent 上等待...?

为什么?

最佳答案

您的代码中的问题是,在 Monitor.Wait(queueLockObj) 退出并且线程可以处理项目之前,另一个线程(ExecuteMTAAction 方法)必须调用 Monitor。 Exit(queueLockObj),但对 item.waitHandle.WaitOne() 的调用阻止了此调用 - 您遇到了死锁。所以 - 您必须在 item.waitHandle.WaitOne() 之前调用 Monitor.Exit(queueLockObj)。此代码可以正常工作:

private void ExecuteMTAAction(Action action)
{
if (IsMTAThread)
action();
else
{
lock (queueLockObj)
{
MarshalThreadItem item = new MarshalThreadItem();
item.Action = action;
item.waitHandle = new ManualResetEvent(false); //setup
marshalThreadItems.Enqueue(item);

Monitor.Pulse(queueLockObj);
}
item.waitHandle.WaitOne(); //waiting
}
}

关于C# 线程同步监视器 + ResetEvent,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13218656/

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