Compact Framework,Windows Mobile 6,C#。我有一個在緊湊框架上的一些後臺線程,並有一個問題:終止工作線程。線程 - 如何通過UI交互來終止工作/後臺線程
守則
我有以下ThreadWorker類(從here碼),在執行時,將執行在某些點進行檢查,看它是否應該退出與否.....
public class ThreadWorker
{
public event EventHandler<ProgressEventArgs> OnProgress;
protected virtual void Progress(ProgressEventArgs args)
{
if (OnProgress != null)
OnProgress(this, args);
}
private void DoLongProcess()
{
// This will take a long time.
Thread.Sleep(15000);
Progress(new ProgressEventArgs("Some info for the UI to display."));
Thread.Sleep(15000);
}
public void DoSomeBackgroundWork()
{
try
{
while (!Stopping)
{
DoLongProcess();
if (Stopping) return;
DoLongProcess();
if (Stopping) return;
DoLongProcess();
if (Stopping) return;
DoLongProcess();
if (Stopping) return;
}
}
finally
{
SetStopped();
}
Console.WriteLine("DoSomeBackgroundWork: Terminating gracefully.");
}
/// <summary>
/// Lock covering stopping and stopped
/// </summary>
readonly object locker = new object();
/// <summary>
/// Whether or not the worker thread has been asked to stop
/// </summary>
bool stopping = false;
/// <summary>
/// Whether or not the worker thread has stopped
/// </summary>
bool stopped = false;
/// <summary>
/// Returns whether the worker thread has been asked to stop.
/// This continues to return true even after the thread has stopped.
/// </summary>
public bool Stopping
{
get
{
lock (locker)
{
return stopping;
}
}
}
/// <summary>
/// Returns whether the worker thread has stopped.
/// </summary>
public bool Stopped
{
get
{
lock (locker)
{
return stopped;
}
}
}
/// <summary>
/// Tells the worker thread to stop, typically after completing its
/// current work item. (The thread is *not* guaranteed to have stopped
/// by the time this method returns.)
/// </summary>
public void Stop()
{
lock (locker)
{
stopping = true;
}
}
/// <summary>
/// Called by the worker thread to indicate when it has stopped.
/// </summary>
void SetStopped()
{
lock (locker)
{
stopped = true;
}
}
}
...和下面的形式啓動線程...
public partial class Test : Form
{
public Test()
{
InitializeComponent();
}
private ThreadWorker myThreadWorker;
private Thread t = null;
private void Test_Load(object sender, EventArgs e)
{
myThreadWorker = new ThreadWorker();
myThreadWorker.OnProgress += new EventHandler<ProgressEventArgs>(myThreadWorker_OnProgress);
}
private void miStart_Click(object sender, EventArgs e)
{
try
{
listResults.Items.Insert(0, "Set-up Thread.");
t = new Thread(myThreadWorker.DoSomeBackgroundWork);
t.Name = "My Thread";
t.Priority = ThreadPriority.BelowNormal;
t.Start();
listResults.Items.Insert(0, "Thread started.");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void miStop_Click(object sender, EventArgs e)
{
try
{
listResults.Items.Insert(0, "Waiting for My Thread to terminate.");
listResults.Refresh();
myThreadWorker.Stop();
t.Join();
listResults.Items.Insert(0, "My Thread Finished.");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private delegate void InsertToListBoxDelegate(String text);
private void InsertToListBox(String text)
{
if (InvokeRequired)
Invoke(new InsertToListBoxDelegate(InsertToListBox), new object[] { text });
else
{
listResults.Items.Insert(0, "{0}".With(text));
listResults.Refresh();
}
}
void myThreadWorker_OnProgress(object sender, ProgressEventArgs e)
{
InsertToListBox(e.Text);
}
}
問題
當我點擊停止按鈕調用...
myThreadWorker.Stop();
t.Join();
listResults.Items.Insert(0, "My Thread Finished.");
...我所期待的是爲ThreadWorker與當前DoLongProcess進行(),直到它有完成後,仍然通過OnProgress事件處理程序和myThreadWorker_OnProgress將事件提交給UI。
然而,實際發生的事情是,當OnProgress提高,應用凍結上線閱讀...
Invoke(new InsertToListBoxDelegate(InsertToListBox), new object[] { text });
問題
我怎麼叫...
myThreadWorker.Stop();
t.Join();
...並仍然響應後臺線程的事件,直到它終止?
非常感謝Brian,第1段真的幫助澄清了一些混淆。還要感謝替代解決方案的想法 - 我會給出一些嘗試.....我不知道現在還有什麼/如何(我期待更多的問題!!!!)再次感謝。 ETFairfax – ETFairfax 2011-06-15 14:21:21