所以我的一些代码就像这样异步调用
Task.Run(() => DoSomethingAsync());
DoSomethingAsync本身调用DoSomething2Async,看起来像这样
private void DoSomething2Async()
{
Something something = new Something(3);
Random rand = new Random();
for (int i = 0; i < 3; i++)
{
something.a = rand.Next(1000);
var task = new Task<int>(()
=> Calculate());
something.ContinueWith((t)
=> CalculateContinuation(something, task.Result));
task.Start();
}
MessageBox.Show("Do Something2 is done");
}
这是Calculate()方法
private int Calculate()
{
for (int i = 0; i < 100000000; i++)
{
var a = 5; // imitate some job
}
return new Random().Next();
}
这是CalculateContinuation()方法
private void CalculateContinuation(Something something, int b)
{
MessageBox.Show(something.a.ToString(), b.ToString());
}
这是类Something
class Something : ICloneable
{
public int a;
public Something(int aa)
{
a = aa;
}
public object Clone()
{
Something clone = new Something(a);
return clone;
}
}
如您所见,Calculate
被调用3次,CalculateContinuation
也会被调用3次,我想传递给CalculateContinuation 2参数,其中一个是调用之前配置的对象(在这种情况下)它是某事物的实例),第二个是Calculate
方法的结果。现在的问题是Calculate
的结果对于每次调用都是不同的(因为它是随机的)并且something.a
对于每个调用也应该是不同的,因为它也是随机的,但每次调用{{1} } hit something指的是在CalculateContinuation
的循环的最后一次迭代中配置的Something实例。 (如果它在循环之前被击中我认为它将引用当时配置的对象)。我的意思是我得到DoSomething2Async
MessageBoxes
的结果不同但Calculate
不是。我一直试图解决这个问题两天我不知道该怎么做。我试图传递something.a
的克隆我试图将something
添加到集合中并在每次迭代时传递最后一个,但没有任何东西给我所需的结果。可能有人有这样的问题。在这种情况下解决方案是什么。提前谢谢
修改
人类可读代码
something
RegisterAllUsers就像这样调用
private void RegisterAllUsers()
{
Person person = new Person(string.Empty);
for (int i = 0; i < 3; i++)
{
person.Name = "Some name"; // different on each iteration
// create registration task
var registrationTask = new Task<bool>(()
=> RegisterUser(person));
// assign continue with, first parameter is person itself and second is the result of RegisterUse
registrationTask.ContinueWith((task)
=> RegistrationCallback(person, registrationTask.Result));
registrationTask.Start();
}
}
private bool RegisterUser(Person person)
{
// do registration stuff
return true; // or false if failes
}
private void RegistrationCallback(Person person, bool succeded)
{
// when this method executed the reference of person is whatever was set in RegisterAllUsers
// for the last time, but i want to have reference to the user which was configured on each iteration
// suppose 1st user is Steve 2nd is Bob and 3rd is Jack
// when this methid is hit the name of the user is Jack on all 3 callbacks but the succeded parameter
// is whatever the RegisterUser returned
// update registered user's status
}
答案 0 :(得分:1)
关于您编辑的部分代码:
Person
只有一个实例:person
。然后用i
开始循环。循环为每个person.Name
填写i
,同时启动任务。不幸的是,在启动任务之前,foreeach循环已完成,person
实例仅包含最后指定的值。因此,您有三个计划任务,每个计划都需要一个person
个实例,该实例只有最后一个值分配给Name
,因为Name
取决于i
我从问题描述。
要解决此问题,请为每个任务创建Person
的实例,并在循环中使用j
变量(闭包问题):
for (int i = 0; i < 3; i++)
{
int j = i;
Person person = new Person(string.Empty);
person.Name = "Some name"; // depends on j this time rather on i
....