0

I am currently trying to get the hange of WCF. To test the concurrent execution of two operations, when using this ServiceBehavior section:

[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple,
                 InstanceContextMode = InstanceContextMode.Single,
                 AddressFilterMode = AddressFilterMode.Prefix)]

I came up with the following XUnit test:

    [Fact]
    public void LongRunningMethod_Two_Calls_To_LongRunningMethod_Execute_And_Return_Concurrently() // This is achieved by setting in Service.cs: ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)
    {
        var timeout1 = 3000;
        var timeout2 = 1;

        var sw1 = new Stopwatch();
        var sw2 = new Stopwatch();

        var task1 = Task.Run(() =>
        {
            sw1.Start();
            client.LongRunningMethod(timeout1, "Call 1 to client.LongRunningMethod(...) finished.");
            sw1.Stop();
        });
        var task2 = Task.Run(() =>
        {
            sw2.Start();
            client.LongRunningMethod(timeout2, "Call 2 to client.LongRunningMethod(...) finished.");
            sw2.Stop();
        });
        Task.WaitAll(new Task[] { task1, task2 });

        Assert.True(sw2.ElapsedMilliseconds < sw1.ElapsedMilliseconds);
    }

With an excerpt (with constructor and destructor) of the test-class being:

public class ImplemenationExplorationTesting : IDisposable
{
    private Service service;
    private Server server;
    private Client client;
    private string constructorArgumentString = "A fixed ctor test value that the service should return.";

    public ImplemenationExplorationTesting()
    {
        service = new Service(constructorArgumentString);
        server = new Server(service);
        server.Open();
        client = new Client();
        client.OpenConnection(server.Uri);
    }

    public void Dispose()
    {
        client.CloseConnection();
        server.Close();
    }

    [Fact]
    public void PingName_SendAndReceiveSimpleMessage_Works()
    {
        var expected = "UserName";
        var actual = client.PingName(expected);
        Assert.Equal(expected, actual);
    }

    [Fact]
    public void StringPassedToTheServiceConstructorIsCorrectlyReturnedByServer()
    {
        var expected = constructorArgumentString;
        var actual = client.GetDefaultString();
        Assert.Equal(expected, actual);
    }
}

This works as expected, when running the test individually. However, when I run multiple tests at the same time, I am getting timing issues and the test fails. From the looks of it, the tests do not run concurrently and uninterrupted, but seem to be "time-sliced", which ends up causing these issues. So the question is:

Is this behavior to be expected and how can I avoid it?

packoman
  • 1,230
  • 1
  • 16
  • 36
  • look into `WhenAll` vs `WaitAll` and making the test async then see if that makes a difference http://stackoverflow.com/questions/6123406/waitall-vs-whenall – Nkosi Sep 12 '16 at 14:10
  • 1
    How as defined InstanceContextMode? It makes difference in multiples requests. I suggest you to read this excellent article, it can help you find out the best combination to your scenario: http://www.codeproject.com/Articles/89858/WCF-Concurrency-Single-Multiple-and-Reentrant-and – Ricardo Pontual Sep 12 '16 at 14:26
  • @RicardoPontual Yes. I should have added that information, here is the complete `ServiceBehavior` section: `[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple, InstanceContextMode = InstanceContextMode.Single, AddressFilterMode = AddressFilterMode.Prefix)]` I am using `InstanceContextMode = InstanceContextMode.Single`, since I will have single client connecting to my server (in a self-hosted instance), which runs a single instance the software we use to control a device. – packoman Sep 12 '16 at 14:36

0 Answers0