我需要开一个"数字"任务(变量但小于10)不并行, 并等待他们全部完成,从每个结果得到。 我从每个中获取结果,保存在列表中,然后最终使用它。
这是我的代码,它正在运作,但我认为必须有更清洁的方法。
导致任务数量
List<String> Arguments = new List<String> { "AA", "BB", "CC" };
List<String> ResultList = new List<String>();
//**AT LEAST I'VE GOT ONE**
Task<String> Tasks = Task<String>.Factory.StartNew(() =>
{
return DoSomething(Arguments[0]);
});
ResultList.Add(Tasks.Result);
for (Int32 i = 1; i < Arguments.Count; i++)
{
ResultList.Add(Tasks.ContinueWith<String>(Result =>
{
return DoSomething(Arguments[i]);
}).Result);
}
//**DO I NEED THIS?? It's working even without!!**
//Tasks.Wait();
for (Int32 i = 0; i < ResultList.Count; i++)
{
textBox1.AppendText(ResultList[i] + Environment.NewLine + Environment.NewLine);
}
答案 0 :(得分:3)
我认为这就是你要做的事情:即开始一大堆并行任务并等待它们全部完成然后继续
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace UnitTestProject2
{
class Class4
{
public void run()
{
List<String> Arguments = new List<String> { "AA", "BB", "CC" };
List<Task<String>> tasks = new List<Task<string>>();
foreach (string arg in Arguments)
{
tasks.Add(
this.DoSomething(arg)
.ContinueWith(t => this.DoSomething(t.Result))
.Unwrap<string>()
);
}
Task.WaitAll(tasks.ToArray());
foreach(Task<string> t in tasks)
{
textBox1 += (t.Result + Environment.NewLine + Environment.NewLine);
}
}
public async Task<string> DoSomething(string arg)
{
return arg;
}
public string textBox1;
}
}
答案 1 :(得分:1)
您不需要Wait()
来电。 Task<T>.Result州的文档:
访问属性的get访问器会阻塞调用线程,直到异步操作完成;它相当于调用Wait方法。
答案 2 :(得分:0)
你可以使用async await
public async List<String> SomeMethod() {
List<String> Arguments = new List<String> { "AA", "BB", "CC" };
List<String> ResultList = new List<String>();
foreach(var argument in Arguments)
{
var result = await DoSomething(argument);
ResultList.Add(result);
}
return ResultList;
}
答案 3 :(得分:0)
截至目前,您的整个代码都是同步运行的。您正在使用Task
创建Task.Result
,然后主动阻止它。
如果您真正了解并行性是什么,并且您确实需要执行与列表中的参数一样多的任务,那么您可以卸载所有这些任务然后异步等待(这是键,异步)完成后:
var arguments = new[] { "A", "B", "C" };
var tasks = arguments.Select(argument => Task.Run(() => DoSomething(argument))).ToList();
while (tasks.Count > 0)
{
var finishedTask = await Task.WhenAny(tasks);
textBox1.AppendText(string.Format("{0}{1}{1}", finishedTask.Result,
Environment.NewLine));
tasks.Remove(finishedTask);
}
修改强> 来自您的评论:
我正在调用一个不允许多次通话的网络API(不是我的) 同时,这就是我需要等待每项任务完成的原因
然后根本不需要每个参数的线程。两件事:
HttpClient
及其XXXAsync
方法(例如GetAsync
)。