2010-06-18 59 views
1

不知道我的標題的措辭以及停止工作,從一個線程,但無論:)使用另一個線程

我有兩個線程:主線程與需要做的工作,一個工作線程包含帶進度條和取消按鈕的表單。在正常的代碼中,這將是另一種方式,但在這種情況下我不能這樣做。

當用戶點擊取消按鈕時,會顯示一個提示,詢問他是否真的要取消工作。問題在於主線程繼續工作。我可以通過主線程停止工作等,但是當他點擊提示上的「是」時,我想讓它停止工作。

例子:

// Main thread work starts here  
    t1 = new Thread(new ThreadStart(progressForm_Start)); 
    t1.Start(); 

    // Working 
    for (i = 0; i <= 10000; i++) 
    { 
     semaphore.WaitOne(); 
     if (pBar.Running) 
      bgworker_ProgressChanged(i); 
     semaphore.Release(); 
     if (pBar.IsCancelled) break; 
    } 

    t1.Abort(); 
// Main thread work ends here 

// Start progress bar form in another thread 
void progressForm_Start() 
{ 
    pBar.Status("Starting"); 
    pBar.ShowDialog(); 
} 

我在理論上包括在cancelWatch()函數的提示,但後來我不得不做,到處都是我實現這個類。

+0

爲什麼你不能把表單放在主線程中,並簡單地使用Swing WorkerThread?這看起來很複雜。 「普通代碼」的含義 – 2010-06-18 16:15:41

+0

「普通代碼」我的意思是我一開始就會想到這樣做。 我不能把表單放在主線程中,因爲我需要能夠在任何時候實際點擊取消按鈕來取消操作。但是我不能使用BackgroundWorker,因爲我不想在這裏使用異步線程。 主線程已經是一個顯示數據並在後臺執行一些操作的窗體。我需要一個進度條和一個取消按鈕,然後在主窗體上進行操作幾乎是不可能的。 – duraz0rz 2010-06-18 16:34:12

回答

1

我有一對夫婦的快速評論:

  1. 避免使用Thread.Abort()here's why
  2. 使您的線程成爲後臺線程:Thread.IsBackground = true(當您的應用程序退出時,它將自動退出線程)。

下面是關於如何安全停止運行一個線程的詳細討論:Is it safe to use a boolean flag to stop a thread from running in C#

要停止在主線程工作,你不得不做這樣的事情:

boolean volatile isRunning = true; 

static void Main(...) 
{ 
    // ... 
    // Working 
    for (i = 0; i <= 10000; i++) 
    { 
     semaphore.WaitOne(); 
     if (!isRunning) break; // exit if not running 
     if (pBar.Running) 
      bgworker_ProgressChanged(i); 
     semaphore.Release(); 
    } 
    //... 
    t1.Interrupt();// make the worker thread catch the exception 
} 
// 
void cancelButton_Click(object sender, EventArgs e) 
{ 
    isRunning = false; // optimistic stop 
    semaphore.Release(); 
} 
+0

好吧,謝謝,當我有機會的時候我必須嘗試一下。 – duraz0rz 2010-06-19 13:24:46

+0

@Duracell,是的,讓我知道它是如何工作的。 – Kiril 2010-06-19 13:39:42

+0

對不起,我沒有回覆你...我們決定嘗試不同的路線,但謝謝你的答案。它至少向我們指出了正確的方向:) – duraz0rz 2010-08-23 18:03:51

1

我推薦使用CancellationTokenSource,它可以處理這種複雜的情況。它是任務並行庫的一部分,但實際上並不一定要與Task對象一起使用;它可以很容易地用於舊式Thread對象。

當然,如果您有時間,我建議將主線程的工作定義爲Task對象(使用TaskScheduler.FromCurrentSynchronizationContext在主UI線程上運行)。

請注意,上面的所有內容都假定.NET 4.0。如果你仍然陷在舊平臺上,你只需要有一個bool cancelled;字段受lock或其他類似的東西的保護。提示:不要撥打Thread.Abort;它是邪惡的。

+0

不幸的是,我們被困在.NET 3.5上,因爲這將是我所需要的:(......無論如何,謝謝! – duraz0rz 2010-06-18 17:18:28