简体   繁体   中英

Windows phone 8 RestSharp request. Async/await

I know it has been asked a lot, but my problem is, that my method won't wait for the request to be completet, even though i have implemented a TaskCompletionSource, which should have done the job, but it doesn't.

public DecksViewModel(bool local)
{
    DList = new List<Deck>();

    if (local)
        InitializeLocalDeckList();
    else
    {
        Dereffering();
    }
}

public async void Dereffering()
{
    var e = await InitilaizeWebDeckList();
    List<DeckIn> decksIn = JsonConvert.DeserializeObject<List<DeckIn>>(e);
    foreach (DeckIn d in decksIn)
    {
        Deck dadd = new Deck();
        dadd.CardCount = 0;
        dadd.Name = d.name;
        dadd.PicturePath = d.image;
        dadd.InstallDirectory = false;
        DList.Add(dadd);
    }

    DataSource = AlphaKeyGroup<Deck>.CreateGroups(DList, System.Threading.Thread.CurrentThread.CurrentUICulture, (Deck s) => { return s.Name; }, true);
}

public Task<String> InitilaizeWebDeckList()
{
    var tcs = new TaskCompletionSource<string>();
    var client = new RestClient("blabla.com");
    var request = new RestRequest("");
    request.AddHeader("Authorization", "Basic blabla");
    client.ExecuteAsync(request, response =>
    {
        test = response.Content;
        tcs.SetResult(response.Content);


    });
    return tcs.Task;
}

So when I call the DecksViewModel constructor, I asyncally try to request the data from a webserver and fill the model. The point is, that the corresponding view "doesn't wait" for the request to fill the model, so it's displayed empty. I use the

List<AlphaKeyGroup<Deck>> DataSource 

to fill a LongListSelector via DataBinding. But DataSource isn't yet set, when it is binded. I hope you can help

You're calling an async method without awaiting it inside the constructor. That's why "it doesn't wait" (because it has nothing to wait on).

It's usually a bad idea to call an async method inside the constructor for that reason combined with the fact that constructors can't be async .

You should redesign your solution accordingly. An option is to have an async static method that creates an instance and await s the procedure:

public static async Task CreateInstance(bool local)
{
    var model = new DecksViewModel();
    if (local)
    {
        await InitializeLocalDeckList();
    }
    else
    {
        await Dereffering();
    }
}

That would allow you to not use async void which should only be used in UI even handlers.

You can read more about other options in Stephen Cleary's blog

You are using async void , which means nobody's gonna wait for that. It's just fire and forget .

I see some misunderstanding in the async keyword here: Your code will only wait for the result of an async method, if you use await. Otherwise that call will just start the async method, but you don't know when it is actually gonna run.

You cannot use await in constructors though.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM