3

In order to test a vendor's DLL in a multi-threaded environment, I want to make sure that specific methods can be called in parallel.

For now I just spawn a few threads and do some operations, but I have no control over which operations are happening at the same time.

I'm a bit lost as to what I should use, between locks and monitors, waithandles, mutex, etc.
It's just for a test app, so no need to be "best practice", I just want to make sure rotating (fast operation) on thread 1 is running at the same time as loading (slow operation) on thread 2.

This is basically what I need:

var thread1 = new Thread(() => {
  // load the data ; should take a few seconds
  Vendor.Load("myfile.json");

  // wait for the thread 2 to start loading its data
  WaitForThread2ToStartLoading();

  // while thread 2 is loading its data, rotate it
  for (var i = 0; i < 100; i++) {
    Vendor.Rotate();
  }
});

var thread2 = new Thread(() => {
  // wait for thread 1 to finish loading its data
  WaitForThread1ToFinishLoading();

  // load the data ; should take a few seconds
  Vendor.Load("myfile.json");

  // this might run after thread 1 is complete
  for (var i = 0; i < 100; i++) {
    Vendor.Rotate();
  }
});

thread1.Start();
thread2.Start();

thread1.Join();
thread2.Join();

I have done something with locks and booleans, but it doesn't work.

thomasb
  • 5,816
  • 10
  • 57
  • 92
  • See https://stackoverflow.com/questions/2538065/what-is-the-basic-concept-behind-waithandle - you should look at using WaitHandles to synchronise the running of code within different threads – auburg Feb 16 '18 at 14:55
  • You might watch out for https://learn.microsoft.com/en-us/dotnet/standard/parallel-programming/dataflow-task-parallel-library to accomplish this. – Alexander Schmidt Feb 16 '18 at 14:56
  • VS has pretty good tooling around freezing and working with threads while debugging; https://msdn.microsoft.com/en-us/library/ms164746.aspx – DiskJunky Feb 16 '18 at 14:57
  • 1
    Just use 2 `ManualResetEvent`s. Use `event.WaitOne()` in place of `WaitForXXX` and `event.Set()` when that XXX happens. – Evk Feb 16 '18 at 15:03

1 Answers1

4

This is just an example how this could be done using wait handles to synchronize threads... I simulated processing with the Thread.Sleep()

ManualResetEvent thread1WaitHandle = new ManualResetEvent(false);
ManualResetEvent thread2WaitHandle = new ManualResetEvent(false);

var thread1 = new Thread(() => {

    Console.WriteLine("Thread1 started");

    // load the data ; should take a few seconds
    Thread.Sleep(1000);

    // wait for the thread 2 to start loading its data
    thread1WaitHandle.Set();
    Console.WriteLine("Thread1 wait");
    thread2WaitHandle.WaitOne(-1);
    Console.WriteLine("Thread1 continue");

    // while thread 2 is loading its data, rotate it
    for (var i = 0; i < 100; i++)
    {
        Thread.Sleep(10);
    }
});

var thread2 = new Thread(() => {

    Console.WriteLine("Thread2 started");

    // wait for thread 1 to finish loading its data
    Console.WriteLine("Thread2 wait");
    thread1WaitHandle.WaitOne(-1);
    Console.WriteLine("Thread2 continue");

    // load the data ; should take a few seconds
    Thread.Sleep(1000);
    thread2WaitHandle.Set();

    // this might run after thread 1 is complete
    for (var i = 0; i < 100; i++)
    {
        Thread.Sleep(10);
    }
});

thread1.Start();
thread2.Start();

thread1.Join();
thread2.Join();
Johnny
  • 8,939
  • 2
  • 28
  • 33