2

I am new to the async await method in C#. I have a function called InitServiceAsync I am new to the async await method in C# which will init the service and get the tokens for this client because AcquireTokenForClient(s).ExecuteAsync() is an async funtion so I use await to wait for authentication data

Then I assign the task.Result return from InitServiceAsync() to _service Will it cause dead lock? Can anyone suggest what is the right way to call AcquireTokenForClient with async/await correctly? Thanks

void fun(){
    Task<ExchangeService> task = InitServiceAsync();
    _service = task.Result;
}
private static async Task<ExchangeService> InitServiceAsync()
       {
           ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2013_SP1, tzi);
           var cca = ConfidentialClientApplicationBuilder
                   .Create(appId)
                   .WithClientSecret(clientSecret)
                   .WithTenantId(tenantId)
                   .Build();
           var s = new string[] { "https://outlook.office365.com/.default" };
           var authResult = await cca.AcquireTokenForClient(s).ExecuteAsync().ConfigureAwait(false);
           service.Credentials = new OAuthCredentials(authResult.AccessToken);
           return service;
       }
Yuan
  • 31
  • 7
  • Where are you calling it from? Is it a constructor? Please post the entirec caller method – Code Name Jack Jul 26 '22 at 09:05
  • Hi @CodeNameJack I have modified the code hope it wil be clear. There is a funtion foo then I want to init service in foo() – Yuan Jul 26 '22 at 09:13

2 Answers2

3

if you use task.Result you will wait for the execution of the async task which will make it more or less synchronous again.

ExchangeService exchangeService = await InitServiceAsync();
_service = exchangeService;

I'm also no expert, there are plenty other devs which will explain it to you better, but thats the way i would handle it :)

The only difference is that the await will not block. Instead, it will asynchronously wait for the Task to complete and then resume

Check here Await vs Task.Result in an Async Method

Timmy
  • 4,098
  • 2
  • 14
  • 34
Cruik
  • 190
  • 1
  • 12
1

With the introduction of Asynchronous Main, I don't think much is left to call an asynchronous Method in a synchronous context.

I would suggest you do,

async Task fun()
{
    _service =await InitServiceAsync();
}

If this code is part of a constructor, then, I would suggest you initialize it first and then inject the initialized version in constructor.

At last, if you are building a library, and want to provide synchronous version of async code, then you can refer to these answers. Suggest you go through at least 3-4 answers before making your decision. How to call asynchronous method in sync

Code Name Jack
  • 2,856
  • 24
  • 40
  • I used this code but got an error like Cannot implicitly convert type from Task to ExchangeService when using ```_service =await InitServiceAsync();``` Is there any suggestion for solve this problem? Thanks!! – Yuan Jul 27 '22 at 01:38
  • With `await` you should not be getting the error, This happens if you don't use the `await` keyword. Type of _service should be `ExchanegService`. Post the exact error if you face this issue. – Code Name Jack Jul 27 '22 at 06:57