我现在正在使用后台服务来处理耗时的操作,同时显示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时出了什么问题?)
答案 0 :(得分:1)
您需要一次处理少量记录。
处理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的值
答案 1 :(得分:-1)
我建议尝试使用BlockingCollection