簡體   English   中英

Function 未執行且 UI 凍結

[英]Function not executed and UI freezes

Yandex Music 有這樣的代碼,通過庫https://github.com/K1llMan/Yandex.Music.Api我正在嘗試進行 UI 綁定,以便應用程序不是控制台,我在NetCore上創建了一個項目3.1 + WPF做了一個 window,用於輸入登錄名和密碼的字段,在按下登錄按鈕loginb后整個 UI 凍結,VS output 中的Console.WriteLine不顯示任何內容。 請告訴我如何解決這個問題?

namespace YDClient
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : MetroWindow
    {
        public MainWindow()
        {
            InitializeComponent();
            Console.WriteLine("Starting");
        }

        private void LaunchGitHubSite(object sender, RoutedEventArgs e)
        {
            // Launch the GitHub site...
        }

        private void loginb(object sender, RoutedEventArgs e)
        {
            DebugSettings debugSettings = new DebugSettings(@"C:\yandex_music", @"C:\yandex_music\log.txt");
            AuthStorage authStorage = new AuthStorage(debugSettings);
            var api = new YandexMusicApi();
            api.User.Authorize(authStorage, name.Text, pass.Text);
            if (authStorage.IsAuthorized)
            {
                Console.WriteLine("Auth true");
            }
            else
            {
                Console.WriteLine("Auth false");
                return;
            }
        }
    }
}

您的loginb function 不是異步方法。 因此,當您的代碼執行時,I/O 請求會阻止該方法的繼續。 您必須按以下方式更改方法;

private async Task loginb(object sender, RoutedEventArgs e)
{
  ....
  await api.User.Authorize(authStorage, name.Text, pass.Text);
  ....

使方法loginb異步后,您必須在 I/O 操作中使用 await。

后台發生了什么? 讓我們深入探討

我們的應用程序包含兩個主要操作。

1. I/O綁定操作

當您在代碼中進行 I/O 操作時,主線程在操作系統級別調用本機 Windows API 來發出 I/O 請求。 然后 OS 為這個 I/O 請求生成 IRP。 這個IRP去.network driver,然后在.network driver IRP Queue中排隊。 網絡板從 IRP 隊列中獲取 IRP 並發出請求。 如果您不在代碼中使用異步,主線程將被此請求阻塞,並且在 IRP 完成之前不會繼續執行代碼。 但是主線程實際上在這里什么都不做。 它只是等待網絡板完成 IRP 請求。 所以你必須使用async/await關鍵字來使其成為非阻塞的。 使用async/await后,您的主線程將不會被 IRP 請求阻塞並繼續執行代碼。 因此,您的 UI 不會凍結。

2. CPU綁定操作

當您的應用程序包含繁重的計算或艱巨的過程時,您應該在不同的線程中執行此操作以獲得性能。 使用這種方法,繁重的計算將在另一個 CPU 核心的另一個線程中完成。 您可以通過使用await Task.Run(()....方法來實現此目的

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM