Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why using Action in this code?

Hi I see following code:

void UpdateMessage (string message)
{
    Action action = () => txtMessage.Text = message;
    this.Invoke (action);
}

Why using Action and then invoke action here? Why not just using txtMessage.Text = message to replace the code in function body?


Update

A fuller version of the code, presented in a comment, reproduced below with syntax highlighting, indentation etc.

public partial class Form1 : Form 
{ 
    public Form1() 
    { 
        InitializeComponent(); 
        new Thread(Work).Start(); 
    } 

    void Work() 
    { 
        Thread.Sleep(5000); 
        UpdateMessage("My Garden"); 
    } 

    void UpdateMessage(string message) { 
        Action action = () => textBox1.Text = message; 
        this.Invoke(action); 
    } 
} 
like image 755
spspli Avatar asked May 10 '11 13:05

spspli


3 Answers

Because this code runs on a different thread from the UI and must be marshalled across to the UI thread with Invoke.

The documentation for Control.Invoke() states:

Executes the specified delegate on the thread that owns the control's underlying window handle.

This is all necessary because the underlying Windows framework requires that operations on a window handle are performed by the thread that owns the window handle.

like image 80
David Heffernan Avatar answered Oct 07 '22 00:10

David Heffernan


If UpdateMessage is called from another thread you need to Invoke into main thread in order to interact with GUI elements

If you use just txtMessage.Text = message you will get CrossThreadOperationException

like image 42
Stecya Avatar answered Oct 07 '22 01:10

Stecya


You should work with a control's properties in the UI thread, otherwise you will receive exception.

Control.Invoke() will execute your delegate by sending windows message to the window message loop.

But you can optimize code to prevent unnecessary thread syncronization when it don't required:

void UpdateMessage (string message)
{
    if(InvokeRequired)
    {
        Invoke((Action)()=>UpdateMessage(message));
        return;
    }

    txtMessage.Text = message;
}
like image 4
Viacheslav Smityukh Avatar answered Oct 06 '22 23:10

Viacheslav Smityukh