したがって、私のコードの一部は、このように非同期的に呼び出されます
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 回呼び出され、3 回CalculateContinuation
も呼び出されます。CalculateContinuation 2 パラメーターに渡したいのですが、1 つは呼び出し前に構成されたオブジェクト (この場合は何かのインスタンス) で、2 番目はメソッドの結果Calculate
。今問題は、の結果はCalculate
呼び出しごとに異なり(ランダムであるため)、something.a
呼び出しごとに異なる必要があるということです。これもランダムですが、何かがヒットするたびにCalculateContinuation
、何かで構成されたインスタンスを参照しますのループの最終反復DoSomething2Async
。(ループの前にヒットした場合、その時点で構成されたオブジェクトを参照すると思います)。私はMessageBoxes
結果Calculate
が異なる場所を取得することを意味しますが、something.a
ではありません。私はこれを2日間解決しようとしてきましたが、何をすべきかわかりません。something
コレクションに sを追加し、各反復で最後を渡そうとしたのクローンを渡そうとしましたがsomething
、望ましい結果が得られません。誰かがこのような問題を抱えているかもしれません。この状況での解決策は何ですか。前もって感謝します
編集:
人間が読めるコード
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());