簡體   English   中英

BackgroundWorker或Task.WhenAll

[英]BackgroundWorker or Task.WhenAll

我現在正在使用后台服務來處理耗時的操作,並同時在UI中顯示進度

但是,現在希望在時間上實現一些性能上的改進(因為當前背景工作者花了更多時間來完成處理)

后台工作者中Do_Work的當前解決方案如下

foreach(string _entry in ArrayList){

  //process the _entry(communicate to a service and store response in Db) and took almost 2-3 seconds for the completion
}

ArrayList包含近25000條記錄。 因此現在需要大約25000 * 3 = 75000秒的時間來進行處理

我正在考慮的新解決方案就像是同時啟動500個項目的50個線程,並等待所有線程完成,如下所示

int failed = 0;
var tasks = new List<Task>();            
for (int i = 1; i < 50; i++)
{
    tasks.Add(Task.Run(() =>
    {

        try
        {
            //Process 500 items from Array .(communicate to a service and store response in Db)
        }
        catch
        {
            Interlocked.Increment(ref failed);
            throw;
        }
    }));
}
Task t = Task.WhenAll(tasks);    //Runs 50 Threads         
try
{
    await t;
}
catch (AggregateException exc)
{
string _error="";
    foreach (Exception ed in t.Exception.InnerExceptions)
    {
       _error+=ed.Message;
    }
     MessageBox.Show(_error);
}
if (t.Status == TaskStatus.RanToCompletion)
    MessageBox.Show("All ping attempts succeeded.");
else if (t.Status == TaskStatus.Faulted)
    MessageBox.Show("{0} ping attempts failed", failed.ToString());

這會有助於減少處理時間嗎? 還是一些更好的方法? 我嘗試使用10的小樣本樣本進行調試,但是看不出太大差異(我在選擇WhenAll時出了點問題?)

您一次只需要處理幾條記錄。

處理具有n個不同任務的n條記錄。 假設n =5。所以有5個不同的任務t1,t2,t3,t4和t5。 一旦任何人完成一行數據的處理,他們就應該開始處理t(1 + n),t(2 + n),t(3 + n),t(4 + n),t(5 + n)等直到處理完所有記錄。

將所有這些處理后的值存儲到字典或列表中,以識別哪個屬於哪個記錄。

就像遞歸函數一樣。

我過去曾經使用過這種方法,它確實大大提高了性能。 您可以根據您的PC配置微調n的值

我建議嘗試使用BlockingCollection

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM