Question about C # delegates

class ClassA { public delegate void WriteLog(string msg); private WriteLog m_WriteLogDelegate; public ClassA(WriteLog writelog) { m_WriteLogDelegate = writelog; Thread thread = new Thread(new ThreadStart(Search)); thread.Start(); } public void Search() { /* ... */ m_WriteLogDelegate("msg"); /* ... */ } } class classB { private ClassA m_classA; protected void WriteLogCallBack(string msg) { // prints msg /* ... */ } public classB() { m_classA = new ClassA(new WriteLog(WriteLogCallBack)); } public void test1() { Thread thread = new Thread(new ThreadStart(Run)); thread.Start(); } public void test2() { m_classA.Search(); } public void Run() { while(true) { /* ... */ m_classA.Search(); /* ... */ Thread.Sleep(1000); } } } 

Why the following code

 ClassB b = new ClassB(); b.test2() 

prints "msg" and this

 ClassB b = new ClassB(); b.test1() 

doesn't print anything?

+6
source share
3 answers

It is likely that your program will exit due to the termination of the stream (or before the stream has time to start). Just as you explicitly created a stream, you need to explicitly wait for the stream to finish!

You need to use Thread.Join or some other method so that the main program waits for the thread to finish.

One possible option using Thread.Join :

 public Thread test2() { ... return thread; } ... b.test2().Join(); // wait for test2 to complete 

Another option using ManualResetEvent :

 class classB { private ManualResetEvent mre = new ManualResetEvent(false); ... private void Run() { ... this.mre.Set(); // we completed our task } public void Wait(); { this.mre.WaitOne(); } 

Then your code calling b.test2() :

 b.test2(); b.Wait(); 
+6
source

Your code works for me, although I had to expose the parts that were omitted from the message. If I didn’t do something that is significantly different from what you are doing, the problem should be somewhere else.

The code below works fine in a console application: I see a “Test” printed at 1 second intervals.

 internal class ClassA { public WriteLog Log { get; set; } public ClassA(WriteLog writeLog) { Log = writeLog; } public void Search() { Log.Print("Test"); } } class classB { private ClassA m_classA; protected void WriteLogCallBack(string msg) { // prints msg /* ... */ Console.WriteLine(msg); } public classB() { m_classA = new ClassA(new WriteLog(WriteLogCallBack)); } public void test1() { Thread thread = new Thread(new ThreadStart(Run)); thread.Start(); } public void test2() { m_classA.Search(); } public void Run() { while (true) { /* ... */ m_classA.Search(); /* ... */ Thread.Sleep(1000); } } } internal class WriteLog { private Action<string> Callback { get; set; } public WriteLog(Action<string> writeLogCallBack) { Callback = writeLogCallBack; } public void Print(string msg) { Callback(msg); } } internal class Program { private static void Main(string[] args) { classB b = new classB(); b.test1(); } } 
+2
source

In what context is b.test1 () called? If this is a console application and the next thing after calling b.test1 () is terminating the program, then the thread created by b.test1 () will probably never be executed until the program terminates.

You need to wait to allow enough time to create a new thread (expensive) and scheduled for execution. “Multithreaded” and “parallel” do not mean instantaneous. They mean a lot of work per unit of time, averaged over most of the work.

To reduce the cost of a background thread operation, consider replacing new Thread() with ThreadPool.QueueUserWorkItem() to use an existing workflow thread. This will save time and memory.

Also, carefully consider whether the work you push into the background thread is really worth the extra overhead. If logging can potentially block file I / O or network I / O, then doing this in the background thread can be dangerous, but there are other methods for performing asynchronous I / O without having to create a new thread.

Also consider the frequency. It would be better to deploy a background thread that will listen on the queue and sleep most of the time, as well as send the main thread's streaming messages to the queue, than to deploy a new thread each time you want to print a few characters of text.

+1
source

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


All Articles