[英]task continuation messes up the references
所以我的一些代碼像這樣異步調用
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());
}
這是類的東西
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
被命中時,某事指的是Something的實例它是在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());
關於您已編輯的部分代碼:
Person
只有一個實例: person
。 然后,您從i
開始循環。 循環填充每個i
person.Name
,與此同時它開始執行任務。 不幸的是,在開始任務之前,前循環已完成,並且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
....
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.