Ragnarokkr Xia
Ragnarokkr Xia

Reputation: 303

Looking for a proper multi thread lock

I'm looking for certain kind of multi thread lock, For example,

ManualResetEvent mre = new ManualResetEvent(false);
new Thread(()=>
{
    //Do something here, we name it "Task 1"
    mre.Set();
}).Start();
mre.WaitOne();
//Do another thing, we name it "Task 2"

This will ensure Task 2 will not be executed until Task 1 is completed.

Now there is another case

    //We assume there are two tasks must be completed before the third can be started
int taskCount = 2;
SomeLock lock = new SomeLock(taskCount);
new Thread(()=>
{
    //Do something here, we name it "Task 1"
    lock.Release();
}).Start();
new Thread(()=>
{
    //Do something here, we name it "Task 2"
    lock.Release();
}).Start();
lock.Wait();
//Do another thing, we name it "Task 3"

The lock is constructed with one parameter indicating the sum of the tasks(in this case, two).

Then lock.Wait() should block the program until both threads complete their task and exit.

It's like a reverse version of Semaphore.

Upvotes: 1

Views: 75

Answers (2)

Enigmativity
Enigmativity

Reputation: 117185

I know this isn't directly answering your question, but this is an alternative approach. Try Microsoft's Reactive Framework (aka Rx) - NuGet System.Reactive and add using System.Reactive.Linq; - then you can do this:

async Task Main()
{
    var query1 =
        from t1 in Observable.Start(() => Task1())
        from t2 in Observable.Start(() => Task2())
        select new { t1, t2 };
        
    var query2 =
        from x in query1
        from t3 in Observable.Start(() => Task3())
        select new { x.t1, x.t2, t3 };
        
    var result = await query2;
}

Now, if the three tasks are actually async themselves, then it is done like this:

async Task Main()
{
    var query1 =
        from t1 in Observable.FromAsync(() => Task1Async())
        from t2 in Observable.FromAsync(() => Task2Async())
        select new { t1, t2 };
        
    var query2 =
        from x in query1
        from t3 in Observable.FromAsync(() => Task3Async())
        select new { x.t1, x.t2, t3 };
        
    var result = await query2;
}

Upvotes: 0

SomeBody
SomeBody

Reputation: 8743

Why don't you use the thread pool and the Task library? It contains the method Task.WaitAll, which can do what you want.

Task task1 = Task.Run(() =>
 {
 // do something
 });

Task task2 = Task.Run(() =>
 {
 // do something else
 });

Task.WaitAll(task1, task2);

Upvotes: 1

Related Questions