在我正在开发的应用程序中,我有一个主要表单,它只是位于那里并显示日志数据,以及一个自动完成循环工作的工作线程.
MyWorker worker = new MyWorker();
MainForm mainForm = new MainForm();
// Subscribe form to log event so log data gets displayed
worker.Log += mainForm.Log;
// Start the worker thread's MainLoop
new Thread(new ThreadStart(worker.MainLoop)).Start();
// Show the form (blocking)
Application.Run(mainForm);
// If we end up here, the form has been closed and the worker has to stop running
worker.Running = false;
Run Code Online (Sandbox Code Playgroud)
如您所见,无论何时关闭表单,都应该停止工作线程.工人看起来像这样:
public class MyWorker
{
public String Running { get; set; }
public MyWorker()
{
Running = true;
}
public void MainLoop()
{
while (Running)
{
DoExtensiveWork1();
if (!Running) return;
DoExtensiveWork2();
if (!Running) return;
DoExtensiveWork3();
if (!Running) return;
DoExtensiveWork4();
if (!Running) return;
DoExtensiveWork5();
if (!Running) return;
// We have to wait fifteen minutes (900 seconds)
// before another "run" can be processed
for (int i = 0; i < 900; i++)
{
Thread.Sleep(1000);
if (!Running) return;
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
如您所见,我希望线程能够在连续的工作操作之间切换时停止,但不能在操作中停止.当一个operation(DoExtensiveWorkN)完成后,它的状态和结果会持久存在于磁盘或数据库中,因此在操作正在进行时(例如,通过Thread.Abort)退出不是一个选项.
但是,我发现这个代码我刚刚写了一些令人厌恶的代码,特别是"等待循环",它休眠了900秒,以防止线程在检测Running到之前空转15分钟false.
我宁愿能够在完成一项工作后立即抛出某种事件来阻止主循环.
任何人都可以指出我正确的方向如何做到这一点,或者如果需要完全重写因为我完全误解了线程,请告诉我哪些原则被解释了?
Iri*_*ium 14
您可以大大整理单个任务的运行和15分钟的等待循环.
我建议也许使用这样的东西:
public class MyWorker
{
private readonly ManualResetEvent _stopEvent = new ManualResetEvent(false);
private readonly Action[] _workUnits;
private bool Running
{
get { return !_stopEvent.WaitOne(0); }
}
public MyWorker()
{
_workUnits = new Action[]
{
DoExtensiveWork1,
DoExtensiveWork2,
DoExtensiveWork3,
DoExtensiveWork4,
DoExtensiveWork5
};
}
public void Stop()
{
_stopEvent.Set();
}
public void MainLoop()
{
while (Running)
{
foreach (var workUnit in _workUnits)
{
workUnit();
if (!Running) return;
}
// We have to wait fifteen minutes (900 seconds)
// before another "run" can be processed
if (_stopEvent.WaitOne(900000)) return;
}
}
}
Run Code Online (Sandbox Code Playgroud)
然后在下一个适当的点停止该过程:
Worker.Stop();
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7522 次 |
| 最近记录: |