Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make sure that all the threads started by the test(s) are stopped before completion

I am building a windows service that communicates with other processes using named pipe. My unit test for the named pipe communication is throwing this error message 4 times:

System.AppDomainUnloadedException: Attempted to access an unloaded AppDomain. This can happen if the test(s) started a thread but did not stop it. Make sure that all the threads started by the test(s) are stopped before completion.

Here's my unit test:

    [TestMethod]
    public void ListenToNamedPipeTest()
    {
        var watcher = new ManualResetEvent(false);

        var svc = new WindowService();
        svc.ClientMessageHandler += (connection, message) => watcher.Reset();
        svc.ListenToNamedPipe();
        sendMessageToNamedPipe("bla");
        var wait = watcher.WaitOne(1000);

        svc.Dispose();

        Assert.IsTrue(wait, "No messages received after 1 seconds");
    }

    private void sendMessageToNamedPipe(string text)
    {
        var client = new NamedPipeClient<Message, Message>(DeviceCertificateService.PIPE_NAME);
        client.ServerMessage += (conn, message) => Console.WriteLine("Server says: {0}", message.Text);

        // Start up the client asynchronously and connect to the specified server pipe.
        // This method will return immediately while the client runs in a separate background thread.
        client.Start();

        client.PushMessage(new Message { Text = text });

        client.Stop();
    }

How do I make all threads stop before my unit test stops?

Thanks


UPDATE:

The named pipe client does not have a close() function:

// Type: NamedPipeWrapper.NamedPipeClient`2
// Assembly: NamedPipeWrapper, Version=1.5.0.0, Culture=neutral, PublicKeyToken=null
// MVID: D2B99F4D-8C17-4DB6-8A02-29DCF82A4118
// Assembly location: C:\Users\Thang.Duong\Source\Workspaces\Post Tracking System\Applications\Dev\OHD\packages\NamedPipeWrapper.1.5.0\lib\net40\NamedPipeWrapper.dll

using System;

namespace NamedPipeWrapper
{
  public class NamedPipeClient<TRead, TWrite> where TRead : class where TWrite : class
  {
    public NamedPipeClient(string pipeName);
    public void Start();
    public void PushMessage(TWrite message);
    public void Stop();
    public void WaitForConnection();
    public void WaitForConnection(int millisecondsTimeout);
    public void WaitForConnection(TimeSpan timeout);
    public void WaitForDisconnection();
    public void WaitForDisconnection(int millisecondsTimeout);
    public void WaitForDisconnection(TimeSpan timeout);
    public bool AutoReconnect { get; set; }
    public event ConnectionMessageEventHandler<TRead, TWrite> ServerMessage;
    public event ConnectionEventHandler<TRead, TWrite> Disconnected;
    public event PipeExceptionEventHandler Error;
  }
}
like image 578
Believe2014 Avatar asked Jul 29 '16 02:07

Believe2014


1 Answers

My WindowsService inherits the ServiceBase class which has the Dispose() function to close all threads. That's why I get all racing errors.

I had to avoid calling Dispose() function and replace it with client.Close() and svc.Close() function. The svc.Close() function is my custom implementation to stop and close the named pipe server.

like image 162
Believe2014 Avatar answered Oct 23 '22 10:10

Believe2014