这是我的情况:
我有一个启动BackgroundWorkers的ThreadManager;我订阅 doWork 事件以在其中记录内容。我还订阅了 BackgroundWorker 本身中的 doWork 事件来处理内容。
嗯,第一个订阅在第二个订阅引发后引发事件。
class ThreadManager
{
//(...)
for (int i = 0; i<100; i++)
{
myWorker wk = new myWorker();
wk.DoWork += new DoWorkEventHandler(wk_DoWork);
}
//(...)
public void wk_DoWork(object sender, DoWorkEventArgs e)
{
Console.Out.Write("PONG");
//(...) Workers Management logic (Pooling, priority, etc.)
}
}
internal class myWorker : : BackgroundWorker
{
//(...)
DoWork += new DoWorkEventHandler(DoMe);
//(...)
void DoMe(object sender, DoWorkEventArgs e)
{
Console.Out.Write("PING");
//(...) Run a 2-3mn file reading process
}
}
出于某种原因,我连续获得所有“Ping”,并在几分钟后开始获得“Pong”。
我在这里缺少什么吗?
编辑:
我本身不使用“控制台”,而是使用异步记录器(即示例)。我仔细观察了“PONG”行的调试过程,在“PING”启动后它就没有被命中。
我的解决方案: 这正是我希望避免的额外代码,但我最终无法消除痛苦。 所以,对于那些有相同问题并在这篇文章中绊倒的人来说:
class ThreadManager
{
//(...)
for (int i = 0; i<100; i++)
{
myWorker wk = new myWorker();
wk.StartedEvent += new myWorker.startDelegate(wk_Started);
}
//(...)
public void wk_Started(params-if-needed)
{
Console.Out.Write("PONG");
//(...) Do Stuff
}
}
internal class myWorker : BackgroundWorker
{
public delegate void startDelegate(string ID);
public event startDelegate StartedEvent;
protected override void OnDoWork(DoWorkEventArgs e)
{
StartedEvent(ID); //put whatever parameter suits you or nothing
base.OnDoWork(e);
e.Result = e.Argument;
Console.Out.Write("PING");
//(...) Do Stuff
}
}
最佳答案
您缺少以下内容:
DoWork 事件的订阅者不是并行调用,而是以串行方式调用,即首先使用 PING 调用处理程序,然后使用 PONG 调用处理程序。因此,当 PING 处理程序需要 3 分钟时,PONG 处理程序将在您调用 RunWorkerAsync
三分钟后执行。
关于C# BackgroundWorker 并行调用 DoWorkEventHandler,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5702730/