2017-03-20 37 views
0

我正在實現一個客戶端,他可以針對某個操作請求某個服務併爲該操作提供一箇中止按鈕。 一旦我使用後臺線程運行動作,中止按鈕應該變爲活動狀態,但整個圖形用戶界面被鼠標圖標固定爲小時玻璃(應該提到動作仍然在發生)。C#.NET - 使用後臺線程但GUI不響應

private void actionButton_Click(object sender, EventArgs e) 
    { 
     Run(RunMode.Action); 
    } 

    private void Run(RunMode runMode) 
    { 
     abortButton.Enabled = true; 
     try 
     { 
      var name = "ds_file"; 
      var url = UrlProvider.BuildRequestUrl(runMode, name); 

      StartLoading($"Running request: {url}"); 

      RunWorker(url); 
     } 
     catch (Exception ex) 
     { 
      AddToLog(ex.ToString()); 
      PopError("Failed to run, see error in log box"); 
     } 

    } 

    private void RunWorker(string url) 
    { 
     var worker = new BackgroundWorker(); 
     worker.DoWork += (sender, args) => 
     { 
      DatabaseHelper.DisableAllJobs(); 
      HttpRequestsHandler.HttpGet(url); 
      DatabaseHelper.EnableRegularJobs(); 
     }; 
     worker.RunWorkerCompleted += (sender, args) => 
     { 
      StopLoading(); 
      abortButton.Enabled = false; 
      if (args.Error != null) 
      { 
       PopError("Failed to run, see error in log box"); 
       AddToLog(args.Error.ToString()); 
      } 
      else 
      { 
       PopInfo("Completed successfully"); 
      } 
     }; 
     worker.RunWorkerAsync(); 
    } 

我在做什麼錯?

謝謝

+0

閱讀這個問:http://stackoverflow.com/questions/31160697/how-to-wait-for-thread-to-complete-without-blocking-ui – NotTelling

+1

在猜測,一些代碼你沒有顯示我們有一個'Invoke',它強制所有東西回到UI線程上。不可能從所示的代碼中看出來,但這是這種情況下的常見錯誤。 –

+1

你能告訴我們你的助手類的方法在DoWork範圍內被調用嗎? –

回答

2

下面的示例運行後臺服務每10秒更新一次GUI。你可以隨意修改它。通過將線程作爲異步任務運行,您的GUI永遠不會掛起。

public frm_testform() 
    { 

     InitializeComponent(); 

     dispatcherTimer_Tick().DoNotAwait(); 

    } 

private async Task dispatcherTimer_Tick() 
    { 
     DispatcherTimer timer = new DispatcherTimer(); 
     TaskCompletionSource<bool> tcs = null; 
     EventHandler tickHandler = (s, e) => tcs.TrySetResult(true); 

     timer.Interval = TimeSpan.FromSeconds(10); 
     timer.Tick += tickHandler; 
     timer.Start(); 

     while (true) 
     { 
      tcs = new TaskCompletionSource<bool>(); 

      await Task.Run(() => 
      { 
      // Run your background service and UI update here 
      await tcs.Task; 
     } 

    } 
0

它確實證明我有controls.enable =僞代碼的某些部分(我真的認爲它完全意味着別的東西),感謝大家的幫助!