2

I have a simple task meant to make a call to the Azure GraphAPI and return the logged in user. The query works and returns the info as expected. The problem is if I try to take that data, assign the data to an object and then return that object. When I do that, the code starts to execute the await graphclient.Me line but never continues. As if it is just waiting for the API to respond.

For some context, I want to return the results so I can use the returned UserModel as a property on a view model.

UserModel is just a simple class with two string properties.

public class UserModel
{
    public string FName { get; set; }
    public string LName { get; set; }
}

I make a call to the task:

 _loggedInUser = GetSignedInUserDetails().Result;

Below is that task that hangs up when trying to return type UserModel. If I modify the task to a void task, it executes without issue.

private async Task<UserModel>  GetSignedInUserDetails()
{
    GraphServiceClient graphClient = await GraphAPIServices
        .SignInAndInitGraph(AzureAppInfo.UserReadAll);

    UserModel loggedInUser = new UserModel();

    var user =  await graphClient.Me
        .Request()
        .GetAsync();

    loggedInUser.LName = user.GivenName;
    loggedInUser.FName = user.Surname;

    return loggedInUser; 
}

I'm sure I am missing something fundamental, I just don't know what it is.

Theodor Zoulias
  • 34,835
  • 7
  • 69
  • 104
GarudaLead
  • 469
  • 1
  • 5
  • 18
  • In `GetSignedInUserDetails` change the first line to `GraphServiceClient graphClient = await GraphAPIServices.SignInAndInitGraph(AzureAppInfo.UserReadAll).ConfigureAwait(false);` and also `.GetAsync().ConfigureAwait(false);` - with that `.ConfigureAwait(false)` you supppress the context switching that will cause the dead lock. Yes, you should also avoid using `Task.Result`. – Sir Rufo Feb 19 '22 at 07:04
  • In reading the the link that was provided in the linked question above (https://blog.stephencleary.com/2012/07/dont-block-on-async-code.html) using ConfigureAwait(false) is not best practice. Best practice would be to have top level methods that async as well. Which brings me to my problem that triggered this question. I can't instantiate a view model as a Task. So how would I load my _loggedInUser object when the vm is instantiated? – GarudaLead Feb 19 '22 at 18:59
  • Well, all my ViewModels have a `Task InitializeAsync(object? parameter, CancellationToken cancellationToken)` method which I call for that reason. – Sir Rufo Feb 19 '22 at 19:14
  • That sounds exactly like what I need. Do you have a link or an example on how best to implement that? I'm trying to wrap my head around all of this. – GarudaLead Feb 19 '22 at 19:58
  • Have a look at https://github.com/SirRufo/WpfWithSplash – Sir Rufo Feb 19 '22 at 22:41
  • I ended up going the route suggested here, under the Data-Bound Values section. Thanks for the help! – GarudaLead Feb 20 '22 at 18:17

0 Answers0