-2

This is from a Microsoft WPF example. The source can be found on git as UsingDispatcher. It is included in a zip file that has a lot of examples.

It is sort of written up here. I have seen it in other places on MSDN (e.g. Threading Model).

I added the commented out line below the error. It works OK. Still, why the error?

private void ForecastButtonHandler(object sender, RoutedEventArgs e)
{
    // Change the status image and start the rotation animation.
    fetchButton.IsEnabled = false;
    fetchButton.Content = "Contacting Server";
    weatherText.Text = "";
    _hideWeatherImageStoryboard.Begin(this);

    // Start fetching the weather forecast asynchronously.
    var fetcher = new NoArgDelegate(FetchWeatherFromServer);

    fetcher.BeginInvoke(null, null);

    //Dispatcher.BeginInvoke(DispatcherPriority.Normal, fetcher);
}

I get a PlatformNotSupportedException at runtime.

PlatformNotSupportedException with fetcher at runtime.

thatguy
  • 21,059
  • 6
  • 30
  • 40
MichaelInMA
  • 151
  • 1
  • 11

1 Answers1

2

The project uses .NET Core 3.1, but BeginInvoke and EndInvoke calls are not supported in .NET Core.

The Asynchronous Programming Model (APM) (using IAsyncResult and BeginInvoke) is no longer the preferred method of making asynchronous calls. The Task-based Asynchronous Pattern (TAP) is the recommended async model as of .NET Framework 4.5. Because of this, and because the implementation of async delegates depends on remoting features not present in .NET Core, BeginInvoke and EndInvoke delegate calls are not supported in .NET Core. This is discussed in GitHub issue dotnet/corefx #5940.

Using BeginInvoke will result in a System.PlatformNotSupportedException at runtime in .NET Core. The reason why it works for Dispatcher is that it was ported to .NET Core with WPF, so it was adapted to not break existing code ported to .NET Core I guess. Another question is why the samples contain this error. One reason is also described in the linked article. The .NET Portability Analyzer does not catch this and this, because the fetcher (NoArgDelegate) is a user-defined delegate.

The reason for this is that BeginInvoke and EndInvoke methods on user-defined delegate types aren’t actually defined in .NET Framework libraries. Instead, these methods are emitted by the compiler (see the ‘Important’ note in Asynchronous Programming Using Delegates) as part of building code that declares a delegate type.

Furthermore, the exception is only thrown at runtime, so you would have to test each project extensively.

thatguy
  • 21,059
  • 6
  • 30
  • 40