2016-11-04 134 views
0

我的代碼有問題。我創建一個圖形應用程序,它有一個主要的形式。當我點擊一個按鈕時,我創建了一個新的窗體,在導出某些文件時顯示進度條。我的問題開始時,我嘗試關閉進度欄的窗體,因爲方法導出文件不結束。關閉窗體時停止線程中的運行方法

在新窗體中,我執行一個方法來檢查導出的進度並填充進度條,每秒執行一次該方法。要導出我創建一個新的線程,並且這個線程執行導出方法。

如果輸出完成,表單和線程關閉正確的方式,但如果我通過關閉窗體「強制」停止操作,導出線程不會停止,直到導出結束或當我關閉主窗體時。

那麼,我該如何阻止該線程?

這是我的代碼:

public Form3(File file, string output, string inputFile) 
    { 
     InitializeComponent(); 
     this.file = file; 
     this.output = output; 
     this.inputFile = inputFile; 
     progressLabel.Location = new Point(textProgress.Right, progressLabel.Top); 
     thread = new Thread((ThreadStart)delegate { Exporter.ExportToFile(this.file, this.output, this.inputFile); }); 
     thread.IsBackground = true; 
     thread.Start(); 

     TimerControl(); 


    } 

    private void TimerControl() 
    { 
     System.Windows.Forms.Timer t = new System.Windows.Forms.Timer(); 
     t.Tick += new EventHandler(GetProgress); 
     t.Interval = 1000; // in miliseconds 
     t.Start();  

    } 

    private void GetProgress(object sender, EventArgs myEventArgs) 
    { 
     int x = Exporter.GetProgress(); 
     progressBar.Maximum = 100; 
     if (!Exporter.stop) 
     { 
      progressBar.Value = x; 
      progressLabel.Text = x.ToString() + "%"; 
     } 
     else 
     { 

      this.Close(); 

     } 
    } 
+0

要做到這一點,你需要添加取消支持'Exporter.ExportToFile()' –

+0

殘酷,但(有點)有效:在你的'閉嘴'事件調用'thread.Abort()' - 任何其他方法當然更可取。 –

+0

這是可怕的建議。 ['永遠不要調用Thread.Abort()'](http://stackoverflow.com/questions/1559255/whats-wrong-with-using-thread-abort)。 –

回答

0

的事情,瞭解這裏:運行該「導出至文件」的代碼(Exporter.ExportToFile)......可能是寫入停止。

換句話說:您想增強該組件。如果你真的想在這樣的背景下使用它,那麼你肯定想要向你的出口商添加另一種方法;如「AbortExport」或類似的東西!

(而不是僅僅殺死例如底層的線程 - 你可能希望確保由出口產生的任何文件被例如去除;以及所有相關資源看到適當的清理)

0

爲什麼不使用任務呢?

https://msdn.microsoft.com/en-us/library/dd997396(v=vs.110).aspx

引述投擲OperationCanceledException並使其在其中要求撤銷令牌。執行此操作的首選方法是使用ThrowIfCancellationRequested方法。以這種方式取消的任務轉換爲取消狀態,調用代碼可以使用該狀態來驗證任務是否響應了取消請求。從https://msdn.microsoft.com/en-us/library/dd997364(v=vs.110).aspx

報價用於實現協作消除模型的一般模式是:

  • 實例化一個CancellationTokenSource對象,其管理併發送取消通知向所述個體取消標記。

  • 將CancellationTokenSource.Token屬性返回的令牌傳遞給偵聽取消的每個任務或線程。

  • 爲每個任務或線程提供響應取消的機制。

  • 調用CancellationTokenSource.Cancel方法來提供取消通知。

見示例代碼在第1條

0

可以使用Thread.Abort();方法,但它不是中止一個線程最佳/最安全的方式

退出線程的最安全的方法是在你的出口類在適當的時候退出添加額外的代碼..

你可以找到噸計算器上的答案與我同意線程應該退出安全由用戶代碼。

編輯:使用Thread.Abort();這是一個糟糕的主意,我認爲這是很明顯的原始答案

+1

[不,你永遠不要使用'Thread.Abort()'](http://stackoverflow.com/questions/1559255/whats-wrong-with-using-thread-abort)。這是非常糟糕的建議。你應該說「你一定不要使用Thread.Abort()」,而不是「你總是可以使用Thread.Abort()」。 –

+0

@MthetheWWatson,你是否讀過整個答案?或者你覺得低調的答案? – Yahfoufi

+0

是的,我讀了整個答案,但第一句還是說'你總是可以使用Thread.Abort(); method'。你應該清楚地表明,你永遠不應該使用這種方法,不要開始你的回答,說你可以「永遠」使用它。你不明白爲什麼這是一個壞主意嗎?只需刪除整個句子,或將其移動到最後並將其改爲「請注意,不應該使用Thread.Abort()'來中止線程」。 –