c# – 处理后完成一个线程循环
我正在寻找C#中的线程安全代码,如果可能的话,将避免两个问题;
>如果线程对象在任何时候被丢弃,则线程循环很好地退出. 线程正在调用一个具有以下while循环的方法; while (!Finished) { string request = ""; try { //Block until we have a message or we are terminated in dispose ** request = server.Recv(Encoding.Unicode); //Send a response to the sender so they know we received. server.Send(request,Encoding.Unicode); } catch (Exception e) { //Catch a termination error. if (e.Errno == ETERM) { break; } } syncContext.Post( new SendOrPostCallback(delegate(object state) { MessageHandler handler = OnMessage; if (handler != null) { handler(request); } }),null); } 处置目前看起来像这样; public void Dispose() { Finished = true; //Cause all blocking message requests and sends to terminate with exception ** FZMQConext.Dispose(); //Wait for the thread to finish up. FThread.Join(); GC.SuppressFinalize(this); } 我认为的问题是; >我的事件可以被调用,即使我正在处理我的类,因为线程必须完成推出.在try / catch和syncContext.Post()之间调用dispos.这有多糟糕? 解决方法
它看起来并不那么糟糕.一旦你设置完成=真.它应该完成发布一个新的委托,然后退出循环.但是,您可能会遇到Finished的CPU缓存问题.运行循环的CPU核心可以在另一个线程更改了值后读取Finished的缓存值,因此循环可能会错误地继续运行.要防止这种情况,您应该创建一个仅通过Interlocked修改的私有字段,以及一个修改该字段的方法: private int _running = 1; public void Stop() { Interlocked.Exchange(ref _running,0); } 并且循环将在(_running> 0)时运行.
实际上没有一般方法可以避免将处置负担放在客户身上.但是如果这个类总是被Winforms组件使用,那么你可以编写一个构造函数来获取父组件并订阅父组件的Disposed事件.因此,当处理父组件(例如表单)时,此对象也会被释放: public MyClass(Component parent) { parent.Disposed += (s,e) => this.Dispose(); } (我会把终结器作为一个选项扔出去,因为无法确定是否/什么时候会运行.) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |