Threading noob here.
I'm trying to make a program that pulls a user's profile data from the osu! website, and while doing so the application freezes. You can't drag around the window or anything. I've tried making a task that returns the result after awaiting but it still freezes
private async Task<OsuUserBest[]> GetUserScores()
{
return await Task.FromResult(osu.GetUserBest(userIdText.Text, 0, 100));
}
private async void OnGoClick(object sender, RoutedEventArgs e)
{
try
{
userScores = await GetUserScores();
//...
and I've also tried doing Task.Run( () => {code})
but it tells me that a different thread owns it. and I can't await osu.GetUserBest(userIdText.Text, 0, 100)
directly because it doesn't contain a definition for GetAwaiter
.
Again I'm extremely new to threads and asynchronous tasks, so please excuse my idiocy =)
If you want me to provide anything else to help out feel free to ask.
CodePudding user response:
You can't access UI elements (or any DispatcherObject
in general) from a thread other than the UI thread (dispatcher thread). Either use the Dispatcher.InvokeAsync
to access those objects or access them (to copy their values) before you run the background operation:
private async Task<OsuUserBest[]> GetUserScoresAsync()
{
// Access the DispatcherObject on the UI thread
string userId = userIdText.Text;
return await Task.Run(() => osu.GetUserBest(userId, 0, 100));
}
Wrapping IO operations like web requests into a Task.Run
should be an absolute exception. Modern APIs will always expose asynchronous operations.