簡體   English   中英

UI 無響應,直到操作完成

[英]UI unresponsive until action is complete

我不確定標題是否很好地描述了這個問題。 本質上,我擁有的是一個 WinForm 應用程序,它將文件夾中的文件列表檢索到 ListView,然后單擊一個按鈕以通過 FTP 將它們上傳到遠程服務器。

從功能上講,該應用程序按預期工作:

  1. 打開應用
  2. 查看 ListView 控件中的文件列表
  3. 點擊上傳按鈕
  4. ListView 中列出的文件被上傳; 每次成功上傳后,ListView 都會更新以顯示“成功”
  5. 上傳所有文件后,操作停止。

我的問題是,單擊上傳按鈕后,用戶界面在操作完成之前幾乎沒有響應。 ListView 在每個文件上傳時按預期更新,甚至保持活動行的焦點。 這是處理文件的 for 循環。 一點背景 - 在下面的代碼摘錄中,每個 for... 循環處理 2 個文件 - 主文件是 ListView 中唯一顯示的文件。 每個循環中的第二個文件是一個觸發器文件,在其主要文件發送后發送,即:.primary、.trigger。 必須發送這兩個文件才能注冊成功。 如果主文件沒有對應的觸發文件,則無法在 ListView 中進行上傳。

foreach (ListViewItem item in lvSourceFiles.Items)
{
    int rowIndex = item.Index;
    string fileName = item.SubItems[2].Text;

    lvSourceFiles.EnsureVisible(rowIndex);

    transferStatus = "Failed"; // Set this as a default

    // Transfer the source file first
    transferResult = session.PutFiles(readyFile, destFile, false, transferOptions);

    // Throw on any error
    transferResult.Check();

    // If the source file transfer was successful, then transfer the trigger file
    if (transferResult.IsSuccess)
    {
        transferResult = session.PutFiles(triggerFile, destFile, false, transferOptions);
        transferResult.Check();

        if (transferResult.IsSuccess)
        {
            transferStatus = "Success";
        }
    }

    UpdateResultsToListView(lvSourceFiles, rowIndex, fileName, transferStatus);
}

這是我需要實現某種異步功能的情況,還是有更好的方法來做到這一點,以便 UI 在上傳過程中不會凍結? 本質上,我希望能夠在上傳運行時與表單進行交互,例如有一個取消按鈕來停止上傳。 就目前而言,在工作完成或終止應用程序之前,我無法對表單進行任何操作。

謝謝,詹姆斯

您可以使用 async/await 和方便的Task.Run方法將長時間運行的操作卸載到ThreadPool線程:

transferResult = await Task.Run(() => session.PutFiles(readyFile, destFile, false, transferOptions));

...和:

transferResult = await Task.Run(() => session.PutFiles(triggerFile, destFile, false, transferOptions));

您還應該在事件處理程序中添加async修飾符,以啟用await運算符。

重要提示:避免在卸載方法中執行任何與 UI 相關的操作。 如果要在操作期間與 UI 進行通信,例如進行進度報告,請使用Progress<T>類。

您不能在 GUI 線程上進行冗長的操作。 在后台線程上執行它們。

@Theodor 的回答正確地表明您可以將PutFiles移動到線程池。

另一種選擇是將所有上傳邏輯移動到線程池,並使用Control.Invoke回調到主線程,僅用於 GUI 更新。

有關完整示例,請參閱 WinSCP 文章在 WinForms ProgressBar 上顯示 FTP/SFTP 傳輸進度

選擇更適合您的選項。 我相信我的方法對於沒有線程編程經驗的人來說更容易掌握。

暫無
暫無

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

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