所以我的一些代码是这样异步调用的
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
也应该不同,因为它也是随机的,但是每次CalculateContinuation
被击中时,都指的是在循环的最终迭代DoSomething2Async
。(如果它会在循环之前被击中,我认为它会引用当时配置的对象)。我的意思是我得到MessageBoxes
的结果Calculate
不同但something.a
不是。这两天我一直在尝试解决这个问题,但我不知道该怎么做。我试图传递something
我试图将something
s 添加到集合并在每次迭代中传递最后一个的克隆,但没有给我想要的结果。可能有人有这样的问题。在这种情况下有什么解决方案。提前致谢
编辑:
人类可读的代码
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
}
RegisterAllUsers 是这样调用的
Task.Run(() => RegisterAllUsers());