.NET Framework Class Library for Silverlight
Dispatcher.BeginInvoke Method (Delegate, Object[])
Executes the specified delegate asynchronously with the specified array of arguments on the thread the Dispatcher is associated with.
Namespace: System.Windows.Threading
Assembly: System.Windows (in System.Windows.dll)
Syntax
Visual Basic (Declaration)
Public Function BeginInvoke ( _ d As Delegate, _ ParamArray args As Object() _ ) As DispatcherOperation
C#
public DispatcherOperation BeginInvoke( Delegate d, params Object[] args )
Parameters
- d
- Type: System.Delegate
A delegate to a method that takes multiple arguments, which is pushed onto the Dispatcher event queue.
- args
- Type: System.Object[]
An array of objects to pass as arguments to the specified method.
Return Value
Type: System.Windows.Threading.DispatcherOperationAn object, which is returned immediately after BeginInvoke is called, that represents the operation that has been posted to the Dispatcher queue.
Examples
The following code example demonstrates how to use this method.
Visual Basic
Private Delegate Sub AddTextDelegate(ByVal p As Panel, ByVal text As String) Private Sub AddText(ByVal p As Panel, ByVal text As String) p.Children.Clear() Dim t As New TextBlock t.Text = text p.Children.Add(t) End Sub Private Sub TestBeginInvokeWithParameters(ByVal p As Panel) If p.Dispatcher.CheckAccess() _ Then AddText(p, "Added directly.") _ Else p.Dispatcher.BeginInvoke(New AddTextDelegate( _ AddressOf AddText), p, "Added by Dispatcher.") End Sub
C#
private delegate void AddTextDelegate(Panel p, String text); private void AddText(Panel p, String text) { p.Children.Clear(); p.Children.Add(new TextBlock { Text = text }); } private void TestBeginInvokeWithParameters(Panel p) { if (p.Dispatcher.CheckAccess()) AddText(p, "Added directly."); else p.Dispatcher.BeginInvoke( new AddTextDelegate(AddText), p, "Added by Dispatcher."); }
Version Information
Silverlight
Supported in: 5, 4, 3Silverlight for Windows Phone
Supported in: Windows Phone OS 7.1, Windows Phone OS 7.0Platforms
For a list of the operating systems and browsers that are supported by Silverlight, see Supported Operating Systems and Browsers.
See Also
Reference
Community Content
Ivo17
A simple workaround around the problem with the lack of the synchronous Invoke method in SLVT
And yes, this is a problem because there are so many cases where the synchronous Invoke is necessary. After all, we can’t even get a result out of the delegate being called in the asynchronous BeginInvoke method. The workaround is based on events, so the code will receive an event when the asynchronous BeginInvoke method is completed. It’s all done in the following class:
class SyncInvoke
{
public Dispatcher disp = null;
public Delegate d = null;
public object[] args = null;
public object result = null;
public object Tag = null;
public delegate void dCompleted(SyncInvoke si);
public event dCompleted Completed = null;
public SyncInvoke(Dispatcher disp, Delegate d, params object[] args)
{
this.disp = disp;
this.d = d;
this.args = args;
}
public void Invoke()
{
if (disp.CheckAccess()) execute();
else disp.BeginInvoke(new dExecute(execute));
}
delegate void dExecute();
void execute()
{
result = d.DynamicInvoke(args);
if (Completed != null) Completed(this);
}
}
The way to use this class is to put all dependent code, of the delegate being invoked, in a separate function, which is going to be called by the Completed event. For example, if you had a code like this:
void test()
{
string st = "";
//st needs the result out of gettext, which is impossible to get with BeginInvoke
this.Dispatcher.BeginInvoke(new dGetText(gettext), new object[] { "testprefix" });
puttext(st);
}
delegate string dGetText(string prefix);
string gettext(string prefix)
{
return prefix + textBox1.Text;
}
void puttext(string st)
{
textBlock1.Text = st;
}
This code will not perform as intended because we can’t get the result out of the gettext function, which is called asynchronously with the BeginInvoke method. You can modify the test function like this, using the SyncInvoke class:
void test()
{
SyncInvoke si = new SyncInvoke(this.Dispatcher, new dGetText(gettext), new object[] { "testprefix" });
si.Completed += new SyncInvoke.dCompleted(si_Completed);
si.Invoke();
}
void si_Completed(SyncInvoke si)
{
string st = si.result.ToString();
puttext(st);
}
class SyncInvoke
{
public Dispatcher disp = null;
public Delegate d = null;
public object[] args = null;
public object result = null;
public object Tag = null;
public delegate void dCompleted(SyncInvoke si);
public event dCompleted Completed = null;
public SyncInvoke(Dispatcher disp, Delegate d, params object[] args)
{
this.disp = disp;
this.d = d;
this.args = args;
}
public void Invoke()
{
if (disp.CheckAccess()) execute();
else disp.BeginInvoke(new dExecute(execute));
}
delegate void dExecute();
void execute()
{
result = d.DynamicInvoke(args);
if (Completed != null) Completed(this);
}
}
The way to use this class is to put all dependent code, of the delegate being invoked, in a separate function, which is going to be called by the Completed event. For example, if you had a code like this:
void test()
{
string st = "";
//st needs the result out of gettext, which is impossible to get with BeginInvoke
this.Dispatcher.BeginInvoke(new dGetText(gettext), new object[] { "testprefix" });
puttext(st);
}
delegate string dGetText(string prefix);
string gettext(string prefix)
{
return prefix + textBox1.Text;
}
void puttext(string st)
{
textBlock1.Text = st;
}
This code will not perform as intended because we can’t get the result out of the gettext function, which is called asynchronously with the BeginInvoke method. You can modify the test function like this, using the SyncInvoke class:
void test()
{
SyncInvoke si = new SyncInvoke(this.Dispatcher, new dGetText(gettext), new object[] { "testprefix" });
si.Completed += new SyncInvoke.dCompleted(si_Completed);
si.Invoke();
}
void si_Completed(SyncInvoke si)
{
string st = si.result.ToString();
puttext(st);
}