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