Search code examples
c#orleans

Using result from inner grain in Orleans


I am trying to understand how Grains work in Orleans. My program will stall when I try to use the result from an inner grain in an outer Grain.

Will the inner grain be blocked by the context of my outer grain, so I can never get the result from an inner grain?

public class OuterGrain : Grain, IOuterGrain
{
    public Task<string> GetFormattedTime()
    {
        var innerGrain = GrainFactory.GetGrain<IInnerGrain>(1);
        var innerGrainTask = innerGrain.GetCurrentTime();
        return Task.FromResult(innerGrainTask.Result.ToString("yy-MM-dd"));
    }
}

public class InnerGrain : Grain, IInnerGrain
{
    public Task<DateTime> GetCurrentTime()
    {
        return Task.FromResult(DateTime.Now);
    }
}

Solution

  • Use the corrent async/await pattern, never use the blocking .Result or .Wait() methods in an async method (that returns Task or Task<>)

    public class OuterGrain : Grain, IOuterGrain
    {
        public async Task<string> GetFormattedTime()
        {
            var innerGrain = GrainFactory.GetGrain<IInnerGrain>(1);
            var innerGrainResult = await innerGrain.GetCurrentTime();
            return innerGrainResult.ToString("yy-MM-dd");
        }
    }
    
    public class InnerGrain : Grain, IInnerGrain
    {
        public Task<DateTime> GetCurrentTime()
        {
            return Task.FromResult(DateTime.Now);
        }
    }