当通过MEF导出类时,如何正确退出后台线程?

时间:2012-06-22 21:35:40

标签: c# .net mef

我实现了充当TcpCLient服务器的类。看起来像这样:

{

[Export]
public class MessageListener
{
    private readonly TcpListener tcpListener;
    private readonly Thread listenThread;

    private DataRepository DataRepository { get; set; }

    private IEventAggregator EventAggregator { get; set; }

    [ImportingConstructor]
    public MessageListener(DataRepository dataRepository, IEventAggregator eventAggregator)
    {
        this.DataRepository = dataRepository;
        this.EventAggregator = eventAggregator;

        // TODO: Need to put proper Port number
        this.tcpListener = new TcpListener(IPAddress.Any, 3000);
        this.listenThread = new Thread(this.ListenForClients);
        this.listenThread.Start();
    }

    private void ListenForClients()
    {
        this.tcpListener.Start();

        while (true)
        {
            // blocks until a client has connected to the server
            var client = this.tcpListener.AcceptTcpClient();

            // create a thread to handle communication with connected client
            var clientThread = new Thread(this.HandleClientComm);
            clientThread.Start(client);
        }
    }

此侦听器在我的Shell视图模型中导入。效果很好。

当我关闭WPF窗口时 - MEF不会处置此对象。 Windows关闭但进程仍在运行。如何正确关闭此服务器"?它等待var client ..

3 个答案:

答案 0 :(得分:1)

在所有前台线程完成之前,该过程不会退出。

在这种情况下,由于您正在开始一个新线程,您可以将其设为后台线程:

this.listenThread = new Thread(this.ListenForClients);
this.listenThread.IsBackground = true;
this.listenThread.Start();

后台线程不会使进程保持活动状态。

答案 1 :(得分:0)

将您的班级标记为实施IDisposable,并在disposed实施中设置Dispose标志。然后改变你接受这样的连接的循环:

    while (!this.disposed)
    {
        Thread.Sleep(1); // to avoid spinning a core 100%
        if (this.tcpListener.Pending)
        {
            // shouldn't block because we checked tcpListener.Pending
            var client = this.tcpListener.AcceptTcpClient();
            var clientThread = new Thread(this.HandleClientComm);
            clientThread.Start(client);
        }
    }

如果您在应用程序退出时自行处理MEF容器,MEF将负责在其创建的任何一次性组件上调用Dispose

答案 2 :(得分:-1)

由于无限循环,它不会停止。您需要使用标志,互斥体或类似的东西,以便循环停止,线程将返回并正确停止。