У меня есть следующий код (https://github.com/avinash0161/OrleansExperiments/tree/c0155b4b0c8c1bfe60aea8624f2cc83a52853dc7):
// Client code
Console.WriteLine("Client making a call");
var hashGenerator = client.GetGrain<IGrainA>(0);
hashGenerator.Call_A_ToTemp();
await Task.Delay(1000);
hashGenerator.Call_B_ToTemp();
// GrainA code
public async Task Call_A_ToTemp()
{
Console.WriteLine("Making call A to a fellow grain");
IGrainB grain = this.GrainFactory.GetGrain<IGrainB>(1);
grain.CallA().ContinueWith((t)=>
{
if(t.IsFaulted)
{
// Silo message timeout is 32s so t.IsFaulted is true
Console.WriteLine("Task Faulted");
Call_A_ToTemp();
}
});
}
public async Task Call_B_ToTemp()
{
Console.WriteLine("Making call B to a fellow grain");
IGrainB grain = this.GrainFactory.GetGrain<IGrainB>(1);
await grain.CallB();
}
// GrainB code
public async Task CallA()
{
Console.WriteLine("Call A came to GrainB");
await Task.Delay(34000); // more than timeout for the caller
}
public Task CallB()
{
Console.WriteLine("Call B came to GrainB");
return Task.CompletedTask;
}
Выходные данные для этого кода:
Client making a call
Making call A to a fellow grain
Call A came to GrainB
Making call B to a fellow grain
Task Faulted <---------------- This comes after Call_B_ToTemp executes
Making call A to a fellow grain
Как мы видим, что Call_B_ToTemp выполняется до того, как Call_A_ToTemp выполняется полностью (ContinueWith части Call_A_ToTemp выполняется позже.) Ожидается ли это и нарушает ли он однопоточный характер зерен?
Когда я заменил код в Call_A_ToTemp () на:
public async Task Call_A_ToTemp()
{
Console.WriteLine("Making call A to a fellow grain");
IGrainB grain = this.GrainFactory.GetGrain<IGrainB>(1);
bool isSuccess = false;
while (! isSuccess)
{
try
{
await grain.CallA();
isSuccess = true;
} catch(TimeoutException){
Console.WriteLine("task faulted");
}
}
}
Код теперь сохраняет однопотоковую природу, и Call_B_ToTemp не вызывается до тех пор, пока не будет выполнена вся ContinueWith
часть Call_A_ToTemp (). Вывод консоли выглядит следующим образом:
Client making a call
Making call A to a fellow grain
Call A came to GrainB
Task Faulted
Making call A to a fellow grain
Может кто-нибудь объяснить, пожалуйстаэто? Является ли однопоточная природа нарушается, когда есть ContinueWith
?