在执行任务时解冻 UI
Unfreeze UI whilst performing a task
这里是线程新手。
我正在尝试制作一个从 osu 中提取用户个人资料数据的程序!网站,同时应用程序冻结。您不能在 window 或任何东西周围拖动。我试过做一个任务 returns 等待后的结果,但它仍然冻结
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();
//...
我也试过 Task.Run( () => {code})
但它告诉我另一个线程拥有它。我不能直接等待 osu.GetUserBest(userIdText.Text, 0, 100)
因为它不包含 GetAwaiter
.
的定义
同样,我对线程和异步任务非常陌生,所以请原谅我的白痴 =)
如果您希望我提供任何其他帮助,请随时提出。
您不能从 UI 线程(调度程序线程)以外的线程访问 UI 元素(或任何 DispatcherObject
一般)。使用 Dispatcher.InvokeAsync
访问这些对象或在 运行 后台操作之前访问它们(复制它们的值):
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));
}
将网络请求等 IO 操作包装到 Task.Run
中应该是绝对的例外。现代 API 将始终公开异步操作。
您并不真的需要 GetUserScores
方法。您可以只使用 Task.Run
method directly inside your asynchronous Click
even handler. This way you'll also avoid violating Microsoft's recommendation 关于不为同步方法公开异步包装器的内容。
您必须知道 Task.Run
方法会在 ThreadPool
线程上调用提供的 lambda,因此无论您卸载什么代码,都不应与 UI 线程有关联。这实际上意味着您不应该触摸(甚至嗅探)卸载代码中的任何 UI 元素。与 UI 组件的交互应该只在 UI 线程上完成。
private async void OnGoClick(object sender, RoutedEventArgs e)
{
try
{
string userId = userIdText.Text;
OsuUserBest[] userScores = await Task.Run(() => osu.GetUserBest(userId, 0, 100));
//...
}
catch (Exception ex)
{
//...
}
}
这里是线程新手。
我正在尝试制作一个从 osu 中提取用户个人资料数据的程序!网站,同时应用程序冻结。您不能在 window 或任何东西周围拖动。我试过做一个任务 returns 等待后的结果,但它仍然冻结
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();
//...
我也试过 Task.Run( () => {code})
但它告诉我另一个线程拥有它。我不能直接等待 osu.GetUserBest(userIdText.Text, 0, 100)
因为它不包含 GetAwaiter
.
同样,我对线程和异步任务非常陌生,所以请原谅我的白痴 =)
如果您希望我提供任何其他帮助,请随时提出。
您不能从 UI 线程(调度程序线程)以外的线程访问 UI 元素(或任何 DispatcherObject
一般)。使用 Dispatcher.InvokeAsync
访问这些对象或在 运行 后台操作之前访问它们(复制它们的值):
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));
}
将网络请求等 IO 操作包装到 Task.Run
中应该是绝对的例外。现代 API 将始终公开异步操作。
您并不真的需要 GetUserScores
方法。您可以只使用 Task.Run
method directly inside your asynchronous Click
even handler. This way you'll also avoid violating Microsoft's recommendation 关于不为同步方法公开异步包装器的内容。
您必须知道 Task.Run
方法会在 ThreadPool
线程上调用提供的 lambda,因此无论您卸载什么代码,都不应与 UI 线程有关联。这实际上意味着您不应该触摸(甚至嗅探)卸载代码中的任何 UI 元素。与 UI 组件的交互应该只在 UI 线程上完成。
private async void OnGoClick(object sender, RoutedEventArgs e)
{
try
{
string userId = userIdText.Text;
OsuUserBest[] userScores = await Task.Run(() => osu.GetUserBest(userId, 0, 100));
//...
}
catch (Exception ex)
{
//...
}
}