How to wait for a method to finish in another thread?

I am new to multithreaded C # programming. My problem is that I donโ€™t know how to wait for a method that runs on another thread to complete before it can continue the next line. For example, something like this

public class A { int i; public A() { i = 0; } protected void RunLoop() { while(i < 100) { i++; } } public void Start() { TimerResolution.TimeBeginPeriod(1); runThread = new Thread(new ThreadStart(RunLoop)); running = true; runThread.Start(); } } public class B { A classAInstance = new A(); A.Start(); Console.Writeline(i); } 

Right now, it is printing 0 on the console, which is not what I want (that is, I = 100). What is the best way to do this? BTW, I do not have access to runThread , which is created in class A

Thanks.

EDIT:

It was a little difficult to solve this problem without changing the code codes. So we ended up adding a condition to public void Start() , with which it can decide whether to run RunLoop in a separate thread or not. The condition was defined using the Enum field.

 public void Start() { TimerResolution.TimeBeginPeriod(1); running = true; if (runningMode == RunningMode.Asynchronous) { runThread = new Thread(new ThreadStart(RunLoop)); runThread.Start(); } else { RunLoop(); } } 

and

 public enum RunningMode { Asynchronous, Synchronous }; 

Thank you all for your help.

+5
source share
3 answers

The preferred method is to use a parallel task library (TPL) and use Task with await .

If you must use Threads, use ManualResetEvent or ManualResetEventSlim to signal the end of the method.

 void Main() { var a = new A(); a.Start(); a.FinishedEvent.WaitOne(); Console.WriteLine(a.Index); } // Define other methods and classes here public class A { ManualResetEvent mre = new ManualResetEvent(false); int i; public EventWaitHandle FinishedEvent { get { return mre; } } public int Index { get { return i; } } public A() { i = 0; } protected void RunLoop() { while (i < 1000) { i++; } mre.Set(); } public void Start() { var runThread = new Thread(new ThreadStart(RunLoop)); runThread.Start(); } } 
+2
source

Your life will be much better with the tasks.

Your code might be so simple:

 var task = Task.Factory.StartNew(() => { var i = 0; while (i < 100) { i++; } return i; }); Console.WriteLine(task.Result); 
+2
source

I like to use Monitor.Wait () and Monitor.Pulse () in combination with the lock statement. It works, but you have to be careful when using this technique. I added some changes to my code to demonstrate this. The code below is prints i == 100, as you want.

 public class A { int i; public object SyncObject { get; private set; } public A() { SyncObject = new object(); i = 0; } protected void RunLoop() { while (i < 100) { i++; } lock (SyncObject) { Monitor.Pulse(SyncObject); } } public void Start() { var runThread = new Thread(new ThreadStart(RunLoop)); runThread.Start(); } public void PrintI() { Console.WriteLine("I == " + i); } } public class B { public static void Run() { A classAInstance = new A(); lock (classAInstance.SyncObject) { classAInstance.Start(); Monitor.Wait(classAInstance.SyncObject); } classAInstance.PrintI(); } } 
0
source

Source: https://habr.com/ru/post/1246073/


All Articles