在這里穿線菜鳥。
我正在嘗試制作一個從 osu 中提取用戶個人資料資料的程式!網站,并且在這樣做時應用程式凍結。你不能在視窗或任何東西上拖動。我試過做一個等待后回傳結果的任務,但它仍然凍結
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.
同樣,我對執行緒和異步任務非常陌生,所以請原諒我的白癡=)
如果您希望我提供其他任何幫助,請隨時詢問。
GitHub存盤庫
uj5u.com熱心網友回復:
您不能DispatcherObject從 UI 執行緒(調度程式執行緒)以外的執行緒訪問 UI 元素(或任何一般元素)。在運行后臺操作之前使用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));
}
將 Web 請求之類的 IO 操作包裝成 aTask.Run應該是絕對的例外。現代 API 將始終公開異步操作。
uj5u.com熱心網友回復:
你真的不需要這個GetUserScores方法。您可以Task.Run直接在異步Click偶數處理程式中使用該方法。這樣,您還可以避免違反 Microsoft關于不為同步方法公開異步包裝器的建議。
您必須知道該Task.Run方法在執行緒上呼叫提供的 lambda ThreadPool,因此您要卸載的任何代碼都不應與 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)
{
//...
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/475815.html
上一篇:當Horizo??ntalAlignment和Horizo??ntalContentAlignment不起作用時,如何使WPF中的控制元件拉伸以填充可用寬度?
