Click to Rate and Give Feedback
MSDN
MSDN Library
.NET Development
.NET Framework 4
Control Class
Control Properties
 InvokeRequired Property
Collapse All/Expand All Collapse All
.NET Framework Class Library
Control..::.InvokeRequired Property

Gets a value indicating whether the caller must call an invoke method when making method calls to the control because the caller is on a different thread than the one the control was created on.

Namespace:  System.Windows.Forms
Assembly:  System.Windows.Forms (in System.Windows.Forms.dll)
Visual Basic
<BrowsableAttribute(False)> _
Public ReadOnly Property InvokeRequired As Boolean
C#
[BrowsableAttribute(false)]
public bool InvokeRequired { get; }
Visual C++
[BrowsableAttribute(false)]
public:
virtual property bool InvokeRequired {
    bool get () sealed;
}
F#
[<BrowsableAttribute(false)>]
abstract InvokeRequired : bool
[<BrowsableAttribute(false)>]
override InvokeRequired : bool

Property Value

Type: System..::.Boolean
true if the control's Handle was created on a different thread than the calling thread (indicating that you must make calls to the control through an invoke method); otherwise, false.

Implements

ISynchronizeInvoke..::.InvokeRequired

Controls in Windows Forms are bound to a specific thread and are not thread safe. Therefore, if you are calling a control's method from a different thread, you must use one of the control's invoke methods to marshal the call to the proper thread. This property can be used to determine if you must call an invoke method, which can be useful if you do not know what thread owns a control.

NoteNote

In addition to the InvokeRequired property, there are four methods on a control that are thread safe to call: Invoke, BeginInvoke, EndInvoke and CreateGraphics if the handle for the control has already been created. Calling CreateGraphics before the control's handle has been created on a background thread can cause illegal cross thread calls. For all other method calls, you should use one of these invoke methods when calling from a different thread.

If the control's handle does not yet exist, InvokeRequired searches up the control's parent chain until it finds a control or form that does have a window handle. If no appropriate handle can be found, the InvokeRequired method returns false.

This means that InvokeRequired can return false if Invoke is not required (the call occurs on the same thread), or if the control was created on a different thread but the control's handle has not yet been created.

In the case where the control's handle has not yet been created, you should not simply call properties, methods, or events on the control. This might cause the control's handle to be created on the background thread, isolating the control on a thread without a message pump and making the application unstable.

You can protect against this case by also checking the value of IsHandleCreated when InvokeRequired returns false on a background thread. If the control handle has not yet been created, you must wait until it has been created before calling Invoke or BeginInvoke. Typically, this happens only if a background thread is created in the constructor of the primary form for the application (as in Application.Run(new MainForm()), before the form has been shown or Application.Run has been called.

One solution is to wait until the form's handle has been created before starting the background thread. Either force handle creation by calling the Handle property, or wait until the Load event to start the background process.

An even better solution is to use the SynchronizationContext returned by SynchronizationContext rather than a control for cross-thread marshaling.

NoteNote

An exception might be thrown if the thread that should process the message is no longer active.

For more information about multithreaded Windows Forms controls, see How to: Use a Background Thread to Search for Files and How to: Make Thread-Safe Calls to Windows Forms Controls.

.NET Framework

Supported in: 4, 3.5, 3.0, 2.0, 1.1, 1.0

.NET Framework Client Profile

Supported in: 4, 3.5 SP1

Windows 7, Windows Vista SP1 or later, Windows XP SP3, Windows XP SP2 x64 Edition, Windows Server 2008 (Server Core not supported), Windows Server 2008 R2 (Server Core supported with SP1 or later), Windows Server 2003 SP2

The .NET Framework does not support all versions of every platform. For a list of the supported versions, see .NET Framework System Requirements.
Tags What's this?: Add a tag
Community Content   What is Community Content?
Add new content RSS  Annotations
Quick and Easy cross-thread call      Barrakoda ... Paul Williams - Wales   |   Edit   |   Show History

privatedelegatevoid UpdateValue(decimal value);
private void MethodToCall(decimal value) {
if
(this.nudSize.InvokeRequired) {
this.Invoke(new UpdateValue(MethodToCall), value);
}
else { nudSize.Value= value;
}
}

Tags What's this?: Add a tag
Flag as ContentBug
Thread-safe utility class for Forms controls      hrmilo   |   Edit   |   Show History
/* hrmilo 2009
* Thread-safety for System.Windows.Forms
* For more information:
* "How to: Make Thread-Safe Calls to Windows Forms Controls"
*/
using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Reflection;
namespace ThreadSafety
{
/// <summary>
/// Class demonstrates a utility to act upon Forms.Control properties.
/// Can be easily adopted to employ Forms.Control methods.
/// Example: "Text[ctrl]" get or set ctrl.Text using ctrl.Invoke if required.
/// </summary>
static class WFControl
{
/// <summary>
/// Perform the given Action delegate on behalf of the given System.Windows.Forms.Control.
/// Use this method when no return type is expected.
/// </summary>
/// <param name="ctrl">The Forms.Control to invoke upon.</param>
/// <param name="action">The control property or method to invoke.</param>
public static void PerformInvoke(Control ctrl, Action action)
{
if (ctrl.InvokeRequired)
{
ctrl.Invoke(action);
}
else
{
action();
}
}
/// <summary>
/// Perform the given Func delegate on behalf of the given System.Windows.Forms.Control.
/// Use this method when a return type is expected.
/// </summary>
/// <typeparam name="T">The type expected to be returned by the control property or method.</typeparam>
/// <param name="ctrl">The Forms.Control to invoke upon.</param>
/// <param name="action">The control property or method to invoke.</param>
/// <returns></returns>
public static T PerformInvoke<T>(Control ctrl, Func<T> action)
{
return ctrl.InvokeRequired ? (T)ctrl.Invoke(action) : action();
}
/// <summary>
/// Convenient generic access to a Forms.Control property.
/// The control is passed as an indexer argument.
/// Example: "Text[ctrl]" will get or set the ctrl.Text property.
/// </summary>
/// <typeparam name="T">The control property's type</typeparam>
public class Property<T>
{
/// <summary>
/// A Func delegate that employs the generic variant of PerformInvoke to emulate a property get method returning type T.
/// </summary>
Func<Control, T> getter;
/// <summary>
/// An Action delegate that employs the non-generic variant of PerformInvoke to emulate a property set method taking type T.
/// </summary>
Action<Control, T> setter;
/// <summary>
/// Func that performs for getter and setter both.
/// bool is false to invoke the getter, true to invoke the setter.
/// Control is the Forms.Control acted upon.
/// Type T is the argument type returned from the getter or passed to the setter.
/// </summary>
Func<bool, Control, T, T> accessor;
/// <summary>
/// Constructor with individualized get and set delegates
/// </summary>
/// <param name="_get">Func delegate to retrieve a control property</param>
/// <param name="_set">Action delegate to set a control property</param>
public Property(Func<Control, T> _get, Action<Control, T> _set)
{
if (_get == null)
{
getter = delegate(Control ctrl) { throw new NotImplementedException(); };
}
else
{
getter = _get;
}
if (_set == null)
{
setter = delegate(Control ctrl, T arg) { throw new NotImplementedException(); };
}
else
{
setter = _set;
}
}
/// <summary>
/// Constructor allowing one delegate to act as both a get delegate and set delegate.
/// Due to the clunky delegate employed, this constructor should not see too much use.
/// </summary>
/// <param name="_accessor">Func delegate providing get and set access to a control property</param>
public Property(Func<bool, Control, T, T> _accessor)
{
if (_accessor == null)
{
getter = delegate(Control ctrl) { throw new NotImplementedException(); };
setter = delegate(Control ctrl, T arg) { throw new NotImplementedException(); };
}
else
{
accessor = _accessor;
getter = delegate(Control ctrl) { return accessor(false, ctrl, default(T)); };//default(T) is ignored
setter = delegate(Control ctrl, T arg) { accessor(true, ctrl, arg); }; //ignores the accessor return value
}
}
/// <summary>
/// Provide convenient and clean way to pass a variety of Forms.Control objects.
/// </summary>
/// <param name="ctrl"></param>
/// <returns></returns>
public T this[Control ctrl]
{
get { return getter(ctrl); }
set { setter(ctrl, value); }
}
}
/// <summary>
/// Predefined Forms.Control properties many users will want to get or set.
/// To provide the look-and-feel of a property, private Property&;;lt;T&;;gt; members are defined and returned through public read-only class properties.
/// This bit of redirection could be eliminated.
/// </summary>
#region standard Control properties

private static Property<string> _text =
new Property<string>(
delegate(Control ctrl) { return PerformInvoke<string>(ctrl, delegate() { return ctrl.Text; }); },
delegate(Control ctrl, string arg) { PerformInvoke(ctrl, delegate() { ctrl.Text = arg; }); }
);
/// <summary>
/// get or set Forms.Control.Text
/// </summary>
public static Property<string> Text
{
get { return _text; }
}

private static Property<object> _tag =
new Property<object>(
delegate(Control ctrl) { return PerformInvoke<object>(ctrl, delegate() { return ctrl.Tag; }); },
delegate(Control ctrl, object arg) { PerformInvoke(ctrl, delegate() { ctrl.Tag = arg; }); }
);
/// <summary>
/// get or set Forms.Control.Tag
/// </summary>
public static Property<object> Tag
{
get { return _tag; }
}
private static Property<string> _name =
new Property<string>(
delegate(Control ctrl) { return PerformInvoke<string>(ctrl, delegate() { return ctrl.Name; }); },
delegate(Control ctrl, string arg) { PerformInvoke(ctrl, delegate() { ctrl.Name = arg; }); }
);
/// <summary>
/// get or set Forms.Control.Name
/// </summary>
public static Property<string> Name
{
get { return _name; }
}
private static Property<bool> _enabled =
new Property<bool>(
delegate(Control ctrl) { return PerformInvoke<bool>(ctrl, delegate() { return ctrl.Enabled; }); },
delegate(Control ctrl, bool arg) { PerformInvoke(ctrl, delegate() { ctrl.Enabled = arg; }); }
);
/* This demonstrates using the accessor delegate rather than separate getter and setter delegates */
//new Property<bool>(
// delegate(bool get_or_set, Control ctrl, bool arg)
// {
// if (get_or_set)
// {
// PerformInvoke(ctrl, delegate() { ctrl.Enabled = arg; }); //perform a set operation
// return false; //return is ignored
// }
// else //performa get operation
// {
// return PerformInvoke<bool>(ctrl, delegate() { return ctrl.Enabled; });
// }
// });
/// <summary>
/// get or set Forms.Control.Enabled
/// </summary>
public static Property<bool> Enabled
{
get { return _enabled; }
}
private static Property<Control.ControlCollection> _controls =
new Property<Control.ControlCollection>(
delegate(Control ctrl) { return PerformInvoke<Control.ControlCollection>(ctrl, delegate() { return ctrl.Controls; }); },
delegate(Control ctrl, Control.ControlCollection arg) { PerformInvoke(ctrl, delegate() { throw new NotSupportedException(); }); }
);
/// <summary>
/// get Forms.Control.Controls
/// </summary>
public static Property<Control.ControlCollection> Controls
{
get { return _controls; }
}
//add your own here, or define them outside of this class
#endregion
}
}
Tags What's this?: Add a tag
Flag as ContentBug
Processing
© 2012 Microsoft. All rights reserved. Terms of Use | Trademarks | Privacy Statement
Page view tracker