退出没有循环的线程
我需要一种方法来停止不包含循环的工作线程。应用程序启动线程,然后线程创建一个FileSystemWatcher对象和一个Timer对象。其中每个都有回调函数。 到目前为止,我所做的就是向线程类添加一个易失性布尔成员,并使用计时器来检查该值。我对设置此值后如何退出线程感到困惑。
protected override void OnStart(string[] args)
{
try
{
Watcher NewWatcher = new Watcher(...);
Thread WatcherThread = new Thread(NewWatcher.Watcher.Start);
WatcherThread.Start();
}
catch (Exception Ex)
{
...
}
}
public class Watcher
{
private volatile bool _StopThread;
public Watcher(string filePath)
{
this._FilePath = filePath;
this._LastException = null;
_StopThread = false;
TimerCallback timerFunc = new TimerCallback(OnThreadTimer);
_ThreadTimer = new Timer(timerFunc, null, 5000, 1000);
}
public void Start()
{
this.CreateFileWatch();
}
public void Stop()
{
_StopThread = true;
}
private void CreateFileWatch()
{
try
{
this._FileWatcher = new FileSystemWatcher();
this._FileWatcher.Path = Path.GetDirectoryName(FilePath);
this._FileWatcher.Filter = Path.GetFileName(FilePath);
this._FileWatcher.IncludeSubdirectories = false;
this._FileWatcher.NotifyFilter = NotifyFilters.LastWrite;
this._FileWatcher.Changed += new FileSystemEventHandler(OnFileChanged);
...
this._FileWatcher.EnableRaisingEvents = true;
}
catch (Exception ex)
{
...
}
}
private void OnThreadTimer(object source)
{
if (_StopThread)
{
_ThreadTimer.Dispose();
_FileWatcher.Dispose();
// Exit Thread Here (?)
}
}
...
}
因此,当线程被告知停止时,我可以处理 Timer / FileWatcher - 但如何实际退出/停止线程?
I need a way to stop a worker thread that does not contain a loop. The application starts the thread, the thread then creates a FileSystemWatcher object and a Timer object. Each of these has callback functions.
What I have done so far is add a volatile bool member to the thread class, and use the timer to check this value. I'm hung up on how to exit the thread once this value is set.
protected override void OnStart(string[] args)
{
try
{
Watcher NewWatcher = new Watcher(...);
Thread WatcherThread = new Thread(NewWatcher.Watcher.Start);
WatcherThread.Start();
}
catch (Exception Ex)
{
...
}
}
public class Watcher
{
private volatile bool _StopThread;
public Watcher(string filePath)
{
this._FilePath = filePath;
this._LastException = null;
_StopThread = false;
TimerCallback timerFunc = new TimerCallback(OnThreadTimer);
_ThreadTimer = new Timer(timerFunc, null, 5000, 1000);
}
public void Start()
{
this.CreateFileWatch();
}
public void Stop()
{
_StopThread = true;
}
private void CreateFileWatch()
{
try
{
this._FileWatcher = new FileSystemWatcher();
this._FileWatcher.Path = Path.GetDirectoryName(FilePath);
this._FileWatcher.Filter = Path.GetFileName(FilePath);
this._FileWatcher.IncludeSubdirectories = false;
this._FileWatcher.NotifyFilter = NotifyFilters.LastWrite;
this._FileWatcher.Changed += new FileSystemEventHandler(OnFileChanged);
...
this._FileWatcher.EnableRaisingEvents = true;
}
catch (Exception ex)
{
...
}
}
private void OnThreadTimer(object source)
{
if (_StopThread)
{
_ThreadTimer.Dispose();
_FileWatcher.Dispose();
// Exit Thread Here (?)
}
}
...
}
So I can dispose the the Timer / FileWatcher when the thread is told to stop - but how do I actual exit/stop the thread?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
我建议使用
ManualResetEvent
,而不是布尔标志。该线程启动FileSystemWatcher
,然后等待事件。当调用Stop
时,它会设置事件:这样您就不必使用计时器,并且您仍然会收到所有通知。
Rather than a Boolean flag, I would suggest using a
ManualResetEvent
. The thread starts theFileSystemWatcher
, then waits on an event. WhenStop
is called, it sets the event:This prevents you from having to use a timer, and you'll still get all your notifications.
当
Start
方法退出时,线程将退出。当你到达计时器时,它已经消失了。The thread will exit when the
Start
method exits. By the time you get to the Timer, it's already gone.一般来说有两种方法可以
There are generally speaking 2 ways to do this
Thread.Abort()
to abort the thread. This is largely considered a very dangerous operation as it will effectively throw an exception and use this to exit the thread. This can very easily lead to leaked resources or forever locked mutexes if the code is not adequetely prepared. I would avoid this approach_StopThread
value at prescribed places and either return out of the method or throw an exception to get back to the thread start and gracefully exit the thread from there. This is the approach favored by the TPL code base (cancellation tokens)在您的情况下,线程不会执行任何操作,因为它会立即退出。您也可以在主线程中创建 Watcher 对象。
即使创建线程终止后,观察者仍继续存在。要摆脱它,请使用 Dispose。
或者,更具体地说,为什么要使用线程?在与主线程不同的线程上处理事件?在这种情况下,请在 Watcher 事件处理程序中创建一个新线程。
必须再次小心地完成此操作,以避免创建过多的线程。典型的解决方案是使用线程池/后台工作者。
In your case, the thread does not do anything as it exits right away. You could create the Watcher object in your main thread as well.
The Watcher continues to exist even after the creating thread terminated. To get rid of it, use Dispose.
Or, more specifically, why do you even want to use a thread? To handle the events on a different thread from the main thread? In that case, create a new thread in the Watcher event handler.
This again has to be done carefully to avoid excessive thread creation. A typical solution is to use a thread pool / background workers.
不要使用 Thread.Start !
使用 TPL、Rx、BackgroundWorker 或更高级别的东西。
Do not use Thread.Start !
Use TPL, Rx, BackgroundWorker or something higher level.
http://msdn.microsoft.com/en-us/library/dd997423.aspx
http://msdn.microsoft.com/en-us/library/dd997423.aspx