Есть вопрос здесь , где обсуждается выполнение задачи Орлеана в контексте ContinueWith
.Я немного изменил пример, чтобы проверить, можно ли сделать так, чтобы две задачи одного и того же зерна в Орлеане чередовались без флага [Reentrant].Весь код здесь .Основные моменты кода следующие:
// Client code
var hashGenerator = client.GetGrain<IHashGeneratorGrain>(0);
Console.WriteLine("Client making a call");
hashGenerator.Call_A_ToTemp();
await Task.Delay(10000);
hashGenerator.Call_B_ToTemp();
// HashGeneratorGrain
public async Task Call_A_ToTemp()
{
Console.WriteLine("Making call A to a fellow grain");
ITempGrain grain = this.GrainFactory.GetGrain<ITempGrain>(1);
// CallA() returns successfully in 20s that is less than the timeout.
grain.CallA().ContinueWith(async (t)=>
{
if (t.IsCompletedSuccessfully)
{
Console.WriteLine("Task success");
Console.WriteLine("Call_A_ToTemp: Counter value now is: " + counter);
var selfGrain = this.GrainFactory.GetGrain<IHashGeneratorGrain>(0);
await selfGrain.IncCounter();
Console.WriteLine("Call_A_ToTemp: after increment: " + this.counter);
}
}
);
}
public async Task IncCounter()
{
this.counter += 1;
}
public async Task Call_B_ToTemp()
{
Console.WriteLine("Call_B_ToTemp called");
Console.WriteLine("Call_B_ToTemp: Counter value now is: " + counter);
Console.WriteLine("Call_B_ToTemp: now sleep for 20s");
await Task.Delay(20000);
Console.WriteLine("Call_B_ToTemp: after sleep value: " + counter);
this.counter += 1;
Console.WriteLine("Call_B_ToTemp: after increment: " + this.counter);
}
// TempGrain
public async Task CallA()
{
Console.WriteLine("Call A came to TempGrain");
await Task.Delay(20000);
}
Вывод этого был:
Client making a call
Making call A to a fellow grain
Call A came to TempGrain
Call_B_ToTemp called
Call_B_ToTemp: Counter value now is: 0
Call_B_ToTemp: now sleep for 20s
Task success
Call_A_ToTemp: Counter value now is: 0
Call_A_ToTemp: after increment: 1
Call_B_ToTemp: after sleep value: 1
Call_B_ToTemp: after increment: 2
Как мы видим, Call_B_ToTemp()
не завершено, но IncCounter()
был вызван между и после выхода, Call_B_ToTemp()
выполнено и завершено.
Разве это не нарушает единственную многопоточность зерен Орлеана?