我们有两个班级:
class MyClass
{
public string str = "something";
public int ind = 5;
public MyClass()
{
}
public void MyMethod()
{
//do something here
}
}
第二个:
class ResultClass
{
private string resultstring;
private int resultint;
public ResultClass(string resultstring, int resultint)
{
this.resultstring = resultstring;
this.resultint = resultint;
}
}
现在在主窗体中,让我们说一下表单加载:
private void Form1_Load(object sender, EventArgs e)
{
List<MyClass> listMyClass = new List<MyClass>();
List<ResultClass> listResultClass = new List<ResultClass>();
MyClass itemMyClass1 = new MyClass();
MyClass itemMyClass2 = new MyClass();
listMyClass.Add(itemMyClass1);
listMyClass.Add(itemMyClass2);
for(int i = 0; i < listMyClass.Count; i++)
{
string s = listMyClass[i].str;
int ind = listMyClass[i].ind;
ResultClass result = new ResultClass(s, ind);
listResultClass.Add(result);
}
}
问题:
我想用任务替换for循环,因此它可以同时计算listResultClass的所有成员。
到目前为止,我找到的最佳方法是尝试这样:
private void Form1_Load(object sender, EventArgs e)
{
List<MyClass> listMyClass = new List<MyClass>();
List<ResultClass> listResultClass = new List<ResultClass>();
MyClass itemMyClass1 = new MyClass();
MyClass itemMyClass2 = new MyClass();
listMyClass.Add(itemMyClass1);
listMyClass.Add(itemMyClass2);
var tasks = listMyClass.Select(t => Task<ResultClass>.Factory.StartNew(() => TestTask(listMyClass))).ToArray();
Task.WaitAll(tasks);
listResultClass.AddRange(tasks.Select(task => task.Result));
}
private ResultClass TestTask(List<MyClass> listMyClass)
{
string s = listMyClass[i].str; //problem here
int ind = listMyClass[i].ind; //and here
ResultClass result = new ResultClass(s, ind);
return result;
}
但我不知道如何操纵[i]值。我尝试声明一个int并将它传递给TestTask,在函数结束时递增它,但它似乎不起作用(可能是因为它在同一时间多次触发,使得int总是为0)。
如何正确替换该循环?
答案 0 :(得分:1)
在我看来,您只需要传递t
,因为这是您要处理的项目:
listMyClass.Select(t => Task.Run(() => TestTask(t)))
或者,您可以获取Select
中项目的索引并在方法中传递该项目:
listMyClass.Select
( (t, idx) => Task.Run
(() => TestTask(listMyClass, idx))
)
答案 1 :(得分:1)
除了使用索引的Select方法的适当覆盖(如已接受的答案中所示)之外,我还建议您不要阻止表单的加载事件。 使其异步
private async void Form1_Load(object sender, EventArgs e)
{
并在
中添加await关键字 var tasks = listMyClass.Select((t, i) => Task.Run(() =>
TestTask(listMyClass, i)));
listResultClass.AddRange(await Task.WhenAll(tasks));
}