none
Did the Dispatcher syntax change with the .Net Framework 3.5 SP1 or VS 2008 SP1 update RRS feed

  • Question

  • Did the Dispatcher object syntax change with the release of the .Net Framework 3.5 SP1 or did Intellisense in Visual Studio 2008 SP1 get changed?

    Whenever I go to use the Dispatcher.Invoke or Dispatcher.BeginInvoke methods in a WPF app post SP1 installation I now see the DispatcherPriority parameter second in the list of required parameters and the Delegate parameter first, where they used to be the other way around, and methods like Dispatcher.CheckAccess() are no longer shown in Intellisense. If you code with the old syntax (i.e. call the Dispatcher.CheckAccess() method even though intellisense tells you it doesn't exist) the methods still behave correctly. Also, the documentation in MSDN is still written against the old syntax.

    This is the case on every one of our developer workstation's here where the developer has upgraded VS and .Net to SP1.

    I've googled this a bit (sorry, haven't tried Live search ;)) and haven't seen anyone mentioning this change anywhere - hence my question.

    Regards,

    Josh.
    Friday, August 29, 2008 1:13 PM

Answers

  • In SP1 we did a few things:

    1) Add BeginInvoke and Invoke overloads that accept a "raw" params arg.  The original overloads took a single arg AND a params arg.  This was intended to help the scenario where you actually wanted to pass an object[] as your only arg.  The "params" keyword normally causes the args you pass to be wrapped in an array.  But if you pass an object[] as the arg, it is NOT wrapped in another array.  I was assured by the C# team that this is by design, but it is problematic.  So we tried to help resolve this situation be specifying the first parameter was a regular object.  Then, internally, we wrap it up in an array if needed.  But this has a couple of problems: 1) it causes extra work and memory allocations, 2) it tries to hide an important aspect of C# which you will probably encounter elsewhere anyways, and 3) it makes passing argument arrays from other dynamic-invoke scenarios to Dispatcher.BeginInvoke/Invoke difficult, as you have to pull the first parameter out of the array you already have instead of just passing it through.

    2) We recevied a lot of feedback that using a raw "delegate" type as the callback made using anonymous delegates and lamda expressions really awkward.  Indeed it did, and with the maturation of .Net, there are now "standard" delegate types.  However, these standard delegate types are in System.Core.dll, which is new to 3.5, so we didn't want to add a dependency like that for a service pack.  So instead, we used "extension methods" to add new BeginInvoke/Invoke methods to the Dispatcher class from the System.Windows.Presentation.dll assembly (which is also new in 3.5).  These are better signatures because they explicitly specify the Action delegate.  If you need to pass in your own delegate type, you can call the original overloads.  We felt the standard pattern presented through IntelliSense should be the new Action overloads.

    CheckAccess and VerifyAccess have always been marked to be not visible, maybe IntelliSense wasn't respecting it.  You can use Reflector to confirm.  The idea here is that CheckAccess and VerifyAccess are advances scenarios, that normal developers don't need.

    However, I do think that EditorBrowsableState.Advanced would have been a more appropriate level.


    Please do not send e-mail directly to this alias. This alias is for newsgroup purposes only.
    • Marked as answer by Josh Norton Wednesday, September 3, 2008 6:49 AM
    Tuesday, September 2, 2008 6:06 PM

All replies

  • Yes, the syntax is changed, the pre-SP1 overloaded method has marked with [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] attributes, so that intellisense will not display them. CheckAccess() method also has this attribute applied, so that you cannot see it in the intellisense too.

    The reason I think is that people always get confused with the pre-SP1 Dispatcher syntax, for instance:

    public DispatcherOperation BeginInvoke(DispatcherPriority priority, Delegate method, object arg);

    public DispatcherOperation BeginInvoke(DispatcherPriority priority, Delegate method, object arg, params object[] args);

    So after SP1, WPF has introduced another overload like this to aggregate the two overload into a single one:

    public DispatcherOperation BeginInvoke(Delegate method, DispatcherPriority priority, params object[] args)

    Hope this helps

     
     
    Tuesday, September 2, 2008 10:00 AM
  • Thanks, makes sense. But why are some methods like CheckAccess() no longer visible in Intellisense?
    Tuesday, September 2, 2008 10:03 AM
  • I am running out of idea, I try to loop someone from the WPF team to comment.

    Thanks
    Tuesday, September 2, 2008 10:38 AM
  • In SP1 we did a few things:

    1) Add BeginInvoke and Invoke overloads that accept a "raw" params arg.  The original overloads took a single arg AND a params arg.  This was intended to help the scenario where you actually wanted to pass an object[] as your only arg.  The "params" keyword normally causes the args you pass to be wrapped in an array.  But if you pass an object[] as the arg, it is NOT wrapped in another array.  I was assured by the C# team that this is by design, but it is problematic.  So we tried to help resolve this situation be specifying the first parameter was a regular object.  Then, internally, we wrap it up in an array if needed.  But this has a couple of problems: 1) it causes extra work and memory allocations, 2) it tries to hide an important aspect of C# which you will probably encounter elsewhere anyways, and 3) it makes passing argument arrays from other dynamic-invoke scenarios to Dispatcher.BeginInvoke/Invoke difficult, as you have to pull the first parameter out of the array you already have instead of just passing it through.

    2) We recevied a lot of feedback that using a raw "delegate" type as the callback made using anonymous delegates and lamda expressions really awkward.  Indeed it did, and with the maturation of .Net, there are now "standard" delegate types.  However, these standard delegate types are in System.Core.dll, which is new to 3.5, so we didn't want to add a dependency like that for a service pack.  So instead, we used "extension methods" to add new BeginInvoke/Invoke methods to the Dispatcher class from the System.Windows.Presentation.dll assembly (which is also new in 3.5).  These are better signatures because they explicitly specify the Action delegate.  If you need to pass in your own delegate type, you can call the original overloads.  We felt the standard pattern presented through IntelliSense should be the new Action overloads.

    CheckAccess and VerifyAccess have always been marked to be not visible, maybe IntelliSense wasn't respecting it.  You can use Reflector to confirm.  The idea here is that CheckAccess and VerifyAccess are advances scenarios, that normal developers don't need.

    However, I do think that EditorBrowsableState.Advanced would have been a more appropriate level.


    Please do not send e-mail directly to this alias. This alias is for newsgroup purposes only.
    • Marked as answer by Josh Norton Wednesday, September 3, 2008 6:49 AM
    Tuesday, September 2, 2008 6:06 PM
  • Thank you, that had me really confused! I agree with you, EditorBrowsableState.Advance would have been more appropriate.
    Wednesday, September 3, 2008 6:51 AM
  • I just downloaded VS2010CTP. The new overloads are missing from .NET 4.0.
    Robert
    Wednesday, November 5, 2008 8:58 AM