加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 处理后完成一个线程循环

发布时间:2020-12-15 21:40:01 所属栏目:百科 来源:网络整理
导读:我正在寻找C#中的线程安全代码,如果可能的话,将避免两个问题; 如果线程对象在任何时候被丢弃,则线程循环很好地退出. 当被另一个类或表单(特别是表单)使用时,使用该类的开发人员不必记住挂钩表单的close事件并调用dispose.例如. Correct finishing of server
我正在寻找C#中的线程安全代码,如果可能的话,将避免两个问题;

>如果线程对象在任何时候被丢弃,则线程循环很好地退出.
>当被另一个类或表单(特别是表单)使用时,使用该类的开发人员不必记住挂钩表单的close事件并调用dispose.例如. Correct finishing of server’s thread

线程正在调用一个具有以下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.这有多糟糕?
>有没有办法包装这个类,所以它的用户不必记得调用dispose.目前,如果他们没有应用程序坐在那里等待线程完成,它永远不会.将它设置为后台线程似乎很懒惰.

解决方法

My event could be called even though I am disposing of my class as the thread has to finish rolling out. Say disposed is called between the try/catch and the syncContext.Post(). How bad is this?

它看起来并不那么糟糕.一旦你设置完成=真.它应该完成发布一个新的委托,然后退出循环.但是,您可能会遇到Finished的CPU缓存问题.运行循环的CPU核心可以在另一个线程更改了值后读取Finished的缓存值,因此循环可能会错误地继续运行.要防止这种情况,您应该创建一个仅通过Interlocked修改的私有字段,以及一个修改该字段的方法:

private int _running = 1;
public void Stop()
{
    Interlocked.Exchange(ref _running,0);
}

并且循环将在(_running> 0)时运行.

Is there any way of wrapping up this class so the user of it doesn’t have to remember to call dispose. Currently if they don’t the application sits there waiting for the thread to finish,which it never will. Setting it to a background thread seems lazy.

实际上没有一般方法可以避免将处置负担放在客户身上.但是如果这个类总是被Winforms组件使用,那么你可以编写一个构造函数来获取父组件并订阅父组件的Disposed事件.因此,当处理父组件(例如表单)时,此对象也会被释放:

public MyClass(Component parent)
{
    parent.Disposed += (s,e) => this.Dispose();
}

(我会把终结器作为一个选项扔出去,因为无法确定是否/什么时候会运行.)

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读