here are some examples of using Invoke() and InvokerRequired() in a multi-threaded forms application to update some controls on the form.
the first one is incrementing a progress bar, and then using Thread.Interlocked.Increment() to increment a counting index by as well.
Code:
private delegate void UpdateStatusDelegate(int inc);
private void UpdateStatus(int inc)
{
UpdateStatusDelegate uptot;
object[] parms = new object[1];
if (this.InvokeRequired == true)
{
parms[0] = 1;
uptot = new UpdateStatusDelegate(UpdateStatus);
this.Invoke(uptot, parms);
}
else
{
pb1.Increment(1);
}
}
implementation would look like this:
in this particular case what is passed to the method is erroneous since i always want the progress bar to increment by one.
this second one passes a control and a boolean for whether or not the control should be enabled to the method:
Code:
private delegate void EnableFormControlDelegate(System.Windows.Forms.Control control, bool enable);
private void EnableFormControl(System.Windows.Forms.Control control, bool enable)
{
EnableFormControlDelegate uptot;
object[] parms = new object[2];
if (this.InvokeRequired == true)
{
parms[0] = control;
parms[1] = enable;
uptot = new EnableFormControlDelegate(EnableFormControl);
this.Invoke(uptot, parms);
}
else
{
control.Enabled = enable;
}
}
implementation would look like this:
Code:
EnableFormControl(cmdStart, true);
both of these are using the object[] method of doing this, passing your parameters in to the array in an order corresponding to the order of your members in the method signature of the target delegate function.
now this one is a little different (aside from the obvious fact that i wrote it in VB.NET). it does NOT use the object[] to pass the information.
Code:
Private Delegate Sub SetButtonEnabledDelegate(ByRef Enable As Boolean)
Private Sub SetButtonEnabled(ByRef Enable As Boolean)
Dim uDel As SetButtonEnabledDelegate
If Me.InvokeRequired = True Then
uDel = New SetButtonEnabledDelegate(AddressOf SetButtonEnabled)
Me.Invoke(uDel, Enable)
Else
cmdImport.Enabled = Enable
End If
End Sub
implementation as follows:
Code:
Call SetButtonEnabled(True)
.NET provides a lot of great multi-threading classes in addition to what you see here. Semaphore/SemaphoreSlim and Threading.Interlocked are two that are rather cool as well. there is also the newer .SyncRoot() property implemented by certain collections for threadsafe operation as well, and as someone mentioned previously ThreadPool can be useful in certain situations as well.