c#后台工作并行调用DoWorkEventHandler
本文关键字:调用 DoWorkEventHandler 并行 工作 后台 | 更新日期: 2023-09-27 17:50:23
我的情况是:
我有一个线程管理器启动后台工作;我订阅了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",几分钟后就开始收到"Pongs"。
我是不是漏掉了什么?
EDIT:
我不使用"控制台"本身,而是使用异步日志记录器(这是示例)。我仔细观察了"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
后3分钟执行。
DoWork
是一个正常事件,使用组播时,它是一个顺序的调用链,BackgroundWorker
不改变这一点。
简而言之,在一个事件上挂起多个事件处理程序是不典型的。
所以,是的,这是非常自然的,因为您在评论中特别提到第一个事件处理程序运行2-3分钟,然后是的,第二个事件处理程序将在几分钟后启动。
据我所知,Console.Out.Write是缓冲的。尝试WriteLine。
这可能无关,但建议在派生类中重写OnXXX
方法,而不是订阅自己的事件。因此,
class MyWorker : BackgroundWorker
{
protected override void OnDoWork(...) { .... }
}
不要忘记调用base.OnDoWork()