关闭侦听事件的线程的正确方法是什么

时间:2017-10-03 16:51:57

标签: c# thread-safety

此问题类似于此处询问的另一个堆栈溢出问题:How to kill a thread instantly in C#? 这个问题很好地解释了问题,并为类似问题提供了解决方案。我的问题是代码是事件驱动的,并且不会在循环中运行。

我正在尝试在关闭我的应用程序时修复错误。该应用程序有一个类在一个线程中实例化,该线程监听事件,一旦获得事件就做一些工作,并继续监听。这些事件可能每次发生一次,也可能发生数万次。所有这一切都运作良好。

这个线程在主应用程序的构造函数中启动,并且应该只在应用程序关闭时结束,但是一半时间线程挂起,并且必须通过任务管理器关闭,另一半时间应用程序崩溃。

结束这个帖子的正确方法是什么?

以下是一些简化的代码:

Public Main_App_Constructor()
{
    ...
    usrIface = new UserInterface();
    usrIface.Start();
    ...
}

private void Application_Exit(object sender, ExitEventArgs e)
{
    ...
    usrIface.Stop();
    ...
}

Public class UserInterface
{
    CommandListener listener;
    Thread listnerThread;   

    Public UserInterface()
    {
        listener = new CommandListener();
        listnerThread = new Thread(new 
        ThreadStart(listner.BeginListneingForEvents));
        listnerThread.SetApartmentState(ApartmentState.STA);
        listnerThread.Name = "Listner";
    }

    Public void Start()
    {
        listnerThread.Start();
    }

    Public void Stop()
    {
        listnerThread.Abort();
    }
}

Public class CommandListener
{
    EventLauncher eventer;

        Public CommandListener()
    {
        eventer = new EventLauncher();

        eventer.event1 += eventer_event1;
        eventer.event2 += eventer_event2;
        eventer.event3 += eventer_event3;
        ...
    }

    private void eventer_event1(object sender, eventArgs e)
    {
        //Does stuff
    }

    private void eventer_event2(object sender, eventArgs e)
    {
        //Does stuff
    }

    private void eventer_event3(object sender, eventArgs e)
    {
        //Does stuff
    }
}

1 个答案:

答案 0 :(得分:-1)

根据Microsoft's documentation

  

不保证线程立即中止,或者根本不中止。

Stack Overflow question here讨论了可能的解决方案。有人建议在线程本身使用共享变量或设置状态变量来要求它停止其操作。另一个建议是添加SecurityPermissionAttribute attribute并将ControlThread设置为true。我自己还没玩过它,但是我会在前进之前从这些地方开始。