2011-04-18 75 views
2

這是我的情況:
我有一個ThreadManager啓動BackgroundWorkers;我訂閱doWork事件來記錄其中的東西。我還訂閱了BackgroundWorker中的doWork事件來處理內容。 那麼,第一次訂閱引發了第二次提出後的事件。C#BackgroundWorker並行調用DoWorkEventHandler

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   
    } 
} 

由於某種原因,我將所有「Pings」連成一行,並在幾分鐘後纔開始獲得Pongs。

有什麼我在這裏失蹤?

編輯:
我不使用「控制檯」本身,而是異步記錄器(這是爲例子)。我一直在仔細觀察「PONG」線上的調試過程,並且在「PING」啓動後它不會受到影響。

我的解決方案: 這正是我希望避免的額外代碼,但我不能最終減輕痛苦。 所以這裏是,對於那些具有相同ISSU和磕磕絆絆對這個職位:

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  
    } 
} 
+0

Side-note,2-3分鐘對於Bgw(ThreadPool)來說很長。 – 2011-04-18 12:28:20

+0

@亨克:你對這個估計有什麼解釋嗎? – 2011-04-18 12:48:03

回答

2

你缺少如下:
DoWork事件的訂戶平行,但以串行方式不叫,即先用你的PING和PONG與處理程序後處理程序。因此,當PING處理程序需要3分鐘時,PONG處理程序將在您調用RunWorkerAsync三分鐘後執行。

+0

哦,上帝,諾路!我確信事件處理是即時的(因爲我曾經在GUI中使用它,從來沒有注意到延遲,因爲太短)。所以。有沒有一種方法來並行化事件處理程序或什麼? – 2011-04-18 12:33:02

0

據我所知,Console.Out.Write緩衝。嘗試WriteLine。

+0

我想這與問題無關。見編輯 – 2011-04-18 12:35:43

+0

噢,好吧。 :-) – 2011-04-18 16:54:40

0

這可能是不相關的,但它的建議覆蓋在派生類OnXXX方法而不是訂閱自己的事件。因此,

class MyWorker : BackgroundWorker 
{ 
    protected override void OnDoWork(...) { .... } 
} 

而且不要忘記調用base.OnDoWork()

+0

是的,我認爲如此,但尚不確定,因爲我不想冒險改變遺留代碼。感謝提示 – 2011-04-18 12:34:37

1

DoWork是一個正常的事件,並與多播,這是一個順序調用鏈,並BackgroundWorker不會改變這一點。

總而言之,掛起多個事件處理程序並不常見。

所以,是的,這是完全自然的,因爲你特別是在你的意見提的是,第一個事件處理程序運行2-3分鐘,那麼,第二個事件處理程序稍後將開始幾分鐘。