Reputation: 3911
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
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,
Have a read of Control.InvokeRequired Property too.
Upvotes: 3
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
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
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
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