babelshift / SteamWebAPI2

🎮 C# / .NET library that makes it easy to use the Steam Web API. It conveniently wraps around all of the JSON data and ugly API details with clean methods, structures and classes.
MIT License
262 stars 43 forks source link

GetPlayerItemsAsync() not finishing. #45

Closed Tvde1 closed 7 years ago

Tvde1 commented 7 years ago

It seems that EconItems.GetPlayerItemsAsync() isn't working anymore. I created a little test:

private const string Key = "[API KEY]";
private const ulong SteamId = 76561198050013009;
private static readonly IEconItems EconItems = new EconItems(Key, EconItemsAppId.TeamFortress2);

And In a method:

var data = await EconItems.GetPlayerItemsAsync(Tvde1SteamId);

Only I'm stepping through this, and it isn't completing even if I leave it running for half an hour. Did something change in steam's api?

babelshift commented 7 years ago

I just tested this with your Steam ID and it worked OK for me. I see 272 items in your inventory. Can you try again? The Steam API often goes down / temporarily unavailable / temporary changes.

Tvde1 commented 7 years ago

I've made a small test project here. You can see the repo here. Whenever I step through the code, it just hangs when I'm getting the inventory data.

babelshift commented 7 years ago

Things get tricky when you starting mixing non-async code and async code. If you can, figure out a way to make the entire stack around the Steam API methods async. I'm not familiar with XAML-based apps, but I'm sure it's possible to make the methods async.

If all else fails, and you really can't go full stack async, I would suggest this approach instead:

public static List<Item> GetAllItems()
{
            var task = EconItems.GetPlayerItemsAsync(Tvde1SteamId);
            task.Wait();
            var data = task.Result;
            return data.Data.Items.Select(x => new Item(x)).ToList();
}

This will block the current thread until the method returns. I doubt this approach would be optimal because it might block the UI thread causing paints to stop and look awful.

Tvde1 commented 7 years ago

But it should be possible to make the async method 'sync' like that right? Well I guess I'll make the entire stack async. I did it this way cause I was calling the method from the constructor,

babelshift commented 7 years ago

GetAwaiter().GetResult() is the same as just using the Result property without actually blocking to wait for the response, which can cause deadlocks and desyncs like you're seeing. See here: http://blog.stephencleary.com/2012/07/dont-block-on-async-code.html.