FosterZ
FosterZ

Reputation: 3911

Need code explanation in C#

I need a detailed explanation of the following code line-by-line and how the flow goes, for example, when I debug. I have just used this code in my program for avoiding a cross thread access error. The code is working fine, but what is this code is all about?

delegate void updateTextField(string Text);
private void updateText(string Text)
{
    if (txtDelegate.InvokeRequired)
    {
        updateTextField del = new updateTextField(updateText);
        txtDelegate.Invoke(del, new object[] { Text });
    }
    else
    {
        txtDelegate.Text = Text;
    }
}

This method is called under backgroundWorker_DoWork():

updateText("using delegate");

I also need an explanation for delegates. I read about it, but what I understood is that a delegate is like a pointer to a function, but I need a clean explanation with a simple example. Think of me as a novice.

Upvotes: 1

Views: 1480

Answers (5)

jasper
jasper

Reputation: 3474

You're spot on when you say a delegate is like a pointer to a method. It allows you to specify, in a safe way, a method,'Foo', as an argument to another method,'Bar', and chances are, the 'Bar' method will call 'Foo' at some stage.

In your above code, the reason you need to do all this work, is due to threading. In Windows Forms, you may have multiple threads in your application, but only the UI thread is allowed to make changes to the controls. So, in the txtDelegate.InvokeRequired line, you're checking to see if the thread is the UI thread or not. If it is, then just set the value of the txtDelegate as normal (in the else portion), if it's not, it gets a little trickier. You then need to tell the UI thread to run some code that will update the value of the textbox, since the current thread cant do it.

To sum it all up,

  • The delegate is the code that contains the instructions to do this,
  • The UI thread is what does it,
  • Your thread asks the UI thread to do it, via the Invoke method.

Have a read of Control.InvokeRequired Property too.

Upvotes: 3

tKe
tKe

Reputation: 560

When updateText is called from the wrong thread (assuming txtDelegate is a control, called from any thread other than the thread it was created on (the UI thread)), the flow is as follows.

updateText(String) called on 'wrong' thread
    txtDelegate.InvokeRequired is true
        wrap updateText(String) in a delegate (updateTextField)
        invoke the delegate on the correct thread (passing Text as parameter)
updateText(String) called on correct thread
    txtDelegate.InvokeRequire is false
        set txtDelegate.Text to Text

When called directly on the "correct" thread (the UI thread):

updateText(String) called on correct thread
    txtDelegate.InvokeRequire = false
        set txtDelegate.Text to Text

Upvotes: 3

Rajesh Subramanian
Rajesh Subramanian

Reputation: 6490

A delegate is like a pointer to the function (I hope you are aware of function pointers in C). So the delegate should have the same signature as a function so that you can point to it.

A cross-thread calls is only allowed in .NET Framework 1.1., it has been stopped after 2.0, So the application checks whether this call is a cross-thread call or normal call using txtDelegate.InvokeRequired, and make a delegate to call the method rather than the real call.....

Otherwise, we can make the normal changes (same thread).

Upvotes: 2

Lazarus
Lazarus

Reputation: 43064

// Declaring a delegate function kind of lifts the function away from the 
// current object and the current thread, making it 'thread-safe' to call 
// (although it may still not be thread-safe to execute).
delegate void updateTextField(string Text); 
private void updateText(string Text)
{
    // This asks the control if it's running on the same thread as this method is 
    // currently executing, i.e. can I update you directly or do I need to use 
    // the cross thread calling method "Invoke".
    if (txtDelegate.InvokeRequired) 
    {
        // Here we define the delegate function that's going to be Invoked. 
        // Here it's the same function were currently within but when it's invoked 
        // by the following line, it'll be done on the same thread as the control. 
        // At that point, InvokeRequired will return false and the other branch 
        // will be followed to update the actual text on the control.
        updateTextField del = new updateTextField(updateText);             

        // Here we invoke the function passing in the Text we want to update the
        // control with as a parameter.
        txtDelegate.Invoke(del, new object[] { Text });         
    }
    else
    {
        // When this function is Invoked, this is the branch that will be followed 
        // (as we're on the same thread as the control) and the text on the control
        //  will be replaced with the text passed in from the Invoke.
        txtDelegate.Text = Text;          
    }
}

I hope that covers it in a bit more detail, the actual mechanics of the delegate being 'thread-safe' is beyond the scope of this answer.

Upvotes: 13

Stephen
Stephen

Reputation: 3084

delegate void updateTextField(string Text); // delegate allows updatetext to be passed as a parameter
private void updateText(string Text) 
{ 
    if (txtDelegate.InvokeRequired) // on a different thread so requires invoke
    { 
        updateTextField del = new updateTextField(updateText); 
        txtDelegate.Invoke(del, new object[] { Text }); // invoke/execute the delegate on the thread
    } 
    else 
    { 
        txtDelegate.Text = Text; 
    } 
} 

Comments added to the code

Upvotes: 3

Related Questions