2012-09-09 125 views
1

我在使用BackgroundWorker時看到了一個問題。會發生什麼情況是BackgroundWorker進程可以正常工作,然後偶爾需要大約40-50秒才能開始。C#BackgroundWorker偶爾需要很長時間才能啓動

該問題發生在兩臺機器上。 BackgroundWorker操作整天都在正常工作,然後在下午這個問題開始出現,這個過程需要40秒而不是1秒,但只是偶爾發生。你可以做5個罰款,第6個將花費40秒。你可以再做5次罰款。如果它開始的時間超過一秒鐘,您可以在workingDialog上按取消,然後立即再次執行,並且它會起作用。在進一步檢查時,似乎該工作人員沒有立即啓動DoWork方法。

我可以用盡線程或什麼?或者,我如何處置BackgroundWorker存在一個問題?代碼如下;

using (workingDialog = new Dialogs.WaitDialog()) { 
    StartThreadedWork(MyDoWorkMethod, customerID); 

    // if user presses cancel button 
    if (workingDialog.ShowDialog() == System.Windows.Forms.DialogResult.Cancel) { 
     m_Worker.RunWorkerCompleted -= ThreadFinished; 
    } 
} 
m_Worker.Dispose(); 
m_Worker = null; 

'StartThreadedWork'方法如下;

private void StartThreadedWork(DoWorkEventHandler method, int customerID) { 
    m_Worker = new BackgroundWorker(); 
    m_Worker.DoWork += method; 
    m_Worker.RunWorkerCompleted += ThreadFinished; 
    object[] parameters = new object [] {customerID }; 
    m_Worker.RunWorkerAsync(parameters); 
} 

最後,分配給DoWork事件處理程序的方法是;

private void ThreadSyncing(object sender, DoWorkEventArgs e) { 
    object[] parameters = e.Argument as object[]; 
    int customerID = (int)parameters[0]; 
    Customer resultCustomer = new Customer(FormsManager.Instance.BillingWebService.Customer_GetByCustomerID(customerID, CustomerSyncOption.Default)); 
    e.Result = resultCustomer; 
} 

一旦RunWorkerCompleted事件被觸發,對話框結果被設置爲OK並且對話框關閉。

對此的任何指針將大大appriciated!

謝謝,

回答

2

你怎麼知道這實際上是BGW的開始被推遲了?你沒有給出任何反饋,你只能看到它完成了。看起來您正在使用Web服務,服務器未響應或完成請求,持續40秒並不正常。默認的tcp/ip連接超時是45秒。

ThreadPool調度程序可以發揮作用,它會嘗試將執行的TP線程數限制爲機器具有的cpu核心數。然而,延遲40秒是一個重要的角落案例。調度程序允許另一個TP線程在現有的線程不完成時啓動,每秒兩次。這樣你就可以擁有80個活動的TP線程來產生這樣的延遲。

有一點值得注意的是你使用的對話框,它實際上並沒有做任何事情來阻止工作者線程。它只是放棄它。所以如果服務器沒有響應並且用戶不耐煩,你可以建立起來。輕敲她的腳四次後,重複按下取消按鈕。 確實導致穩步增加的延遲。您應該使用CancelAsync()方法並使用CancellationPending屬性實現取消邏輯。但是,對於Web服務來說,這通常不容易。

通過提供更好的反饋解決該問題。當用戶取消後不要取消訂閱RunWorkerCompleted事件。只需設置一個標誌,指示最後一次請求被取消。在UI中顯示該Web服務在工作完成之前不可用。包括不允許用戶再次啓動Web服務請求。

+0

如果我刪除了線程並且只是調用web服務,它總能正常工作,並且永遠不會超時。所以我有理由相信它不是Web服務超時。我的問題是不允許用戶再次啓動請求,直到完成爲止,他們將不得不等待該線程完成40秒。正如我所說,如果我刪除線程,它每次都有效。這樣做的唯一問題將是,如果由於某種原因網絡服務停止或失去連接,用戶界面將停止響應:-(謝謝你的答覆雖然! – creatiive

+0

我不是在談論Web服務超時,我這意味着**用戶**超時,給她一個取消按鈕,她將使用它。 –

+0

另外...我不知道如果我只是看着這個,試圖找到一些東西..但因爲我beging在我調用'ShowDialog()'之前的「startThreadedWork」..線程是否可以完成,並且如此快速地設置dialogresult以至於'ShowDialog()'尚未設法啓動,因此不會偵聽對話結果的更改。 ? – creatiive

1

BackgroundWorker使用.Net線程池執行其DoWork方法。

如果你在線程池中加載了太多的負載,一些工作項將被延遲,直到它有一個線程可用來處理它們。

+0

如果您使用池中最後一個可用線程,則會發生這種情況,然後調用BackgroundWorker.RunWorkerAsync。線程池至少需要1秒才能創建一個新線程(假設另一個線程在此期間不可用)。如果CPU負載很重,那麼1秒鐘可能會更長。 –

+0

有沒有辦法查看/增加可用線程的數量?然而,這會覺得我正在改變一些東西來適應糟糕的設計。 – creatiive

相關問題