Threading Question

I use the following method to show a modeless message box.

public void ShowMessageBox(string Message) { var thread = new Thread( () => { MessageBox.Show(Message); }); thread.Start(); } 

"() => {...}" is something that I have never seen before. What is the name of this code template?

In addition, thread.Start starts the thread, and it automatically closes after the completion of the "() => {...}" method (when the message box is "OK"), right? If so, can you point me to any official documentation that the thread automatically closes?

Thanks!

+4
source share
5 answers

It is a lambda operator and reads as "going." MSDN has a good introduction: Lambda Expressions (C # Programming Guide)

One of the problems in your example is that you create a new thread for updating the user interface, the user interface is essentially single-threaded, so updating the background is usually not as it should (unless you manually or explicitly check InvokeRequired and invoke Invoke() if necessary Invoke() .


Regarding user interface streaming ...

In WinForms, each Form or Control is created in a specific thread (a "user interface thread"), and you may think that this thread is the owner of this control (not quite correct, but a good way to conceptualize it). Updating the user interface from this thread is safe, updating the user interface from another thread causes the risk of collisions and corruption and all the usual risks of parallel / asynchronous programming.

... So ... how do you safely update the user interface from a background thread without blocking the user interface? In short - you cannot - the best thing you can do is to block it for the minimum minimum required to update the user interface. Here InvokeRequired and Invoke() come in ...

Here is an example: you can leave this in the code for the new form using the button and text field.

Use:

  • Try commenting on the call to SetTextAsyncSafe() or SetTextAsyncSafe() - running both of them can be confusing since they will not necessarily be executed in the order in which they are called (they work async, remember?).

  • Then set a breakpoint on SetText() . You should see that the "safe" call will actually call this method twice - the first call will detect InvokeRequired and call the 2nd time method for the correct Invoke() 'stream to it.

  • You should see that Exception is SetTextAsyncUnsafe() when SetTextAsyncUnsafe() does receive textBox1.Text = value; . An exception will be an InvalidOperationException with a message stating that the Cross-Stream operation is invalid - you can use this term for this site for more details.

The code:

 private void button1_Click(object sender, EventArgs e) { SetTextAsyncSafe("This update was made from the UI Thread by using Invoke()"); SetTextAsyncUnsafe("This update was made directly from the background thread and can cause problems"); } private void SetTextAsyncUnsafe(string value) { new Thread(() => SetText(value, false)).Start(); } private void SetTextAsyncSafe(string value) { new Thread(() => SetText(value, true)).Start(); } private void SetText(string value, bool checkInvokeRequired) { if (checkInvokeRequired) { if (InvokeRequired) { Invoke(new Action(() => SetText(value, checkInvokeRequired))); return; // early exit } } textBox1.Text = value; } 
+7
source

This is a lambda. In this case, you use it to create a new anonymous method that will be launched when a new thread starts.

This is the (almost) equivalent:

 public void ShowMessageBox(string Message) { var thread = new Thread(ShowBox); thread.Start(Message); } public void ShowBox(object message) { MessageBox.Show(message.ToString()); } 
+3
source

This is called a lambda expression. You can read it here .

+2
source

Lambda expression, C # function version 3.

Do not use this code. A parent window is required in the message box, which can be run on top of it. Usually he can find the parent, iterating through the windows that were created in the same thread. However, in this case there are no other windows; he must select the desktop window as the parent.

This will not work well, when the user works in the application window or switches focus to another application, the message window disappears outside the foreground window. There is no obvious way for the user to say that he is, she will simply lose. It could be hours, if not days, before she returns. However, this thread consumes resources poorly, you probably would never think about it if you knew that this message box requires a megabyte of memory. In extreme cases, you will break the program using OOM.

A common alternative in programming the Windows user interface is the tooltip provided by NotifyIcon. Or your own form with the TopMost property set to True so that it cannot be easily lost. It also allows you to control the position important for β€œmodeless” notifications that should not interfere. Set the ShowWithoutActivation property for this form to true in the form constructor so that it does not steal focus.

+2
source

Lambda property

Yes, the thread is active while this anonymous method is running. Since there are no other statements after MessageBox.Show (), the stream will be completed, and this should be true ... if in doubt, add this before starting:

 thread.Name = "LALALA"; 

And then debug your application. When the message box appears, pause execution, go to the "View of threads" and you will see that LALALA is working. Click "OK" and pause again, there should not be "LALALA" ... =)

+1
source

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


All Articles