Thorsten Westheider Thorsten Westheider - 1 month ago 6
C# Question

InvalidCastException when sharing data and adding to ObservableCollection

I'm trying to send data from Edge to my UWP app using the share contract. It works like a charm, except when I try to add the data received in this way into an

ObservableCollection<T>
I get this exception:


InvalidCastException:
Unable to cast COM object of type 'System.Collections.Specialized.NotifyCollectionChangedEventHandler' to class type 'System.Collections.Specialized.NotifyCollectionChangedEventHandler'. Instances of types that represent COM components cannot be cast to types that do not represent COM components; however they can be cast to interfaces as long as the underlying COM component supports QueryInterface calls for the IID of the interface.*


Code looks as follows:

App.xaml.cs:

protected override void OnShareTargetActivated(ShareTargetActivatedEventArgs args)
{
if (this.SharingService != null)
await this.SharingService.OnShareTargetActivated(args);
}


SharingService.cs:

public delegate void UriAddedEventHandler(object sender, UriAddedEventArgs args);
public event UriAddedEventHandler UriAdded;

public async Task OnShareTargetActivated(ShareTargetActivatedEventArgs args)
{
var shareOperation = args.ShareOperation;

if (shareOperation.Data.Contains(StandardDataFormats.WebLink))
{
var uri = await shareOperation.Data.GetWebLinkAsync();

this.UriAdded?
.Invoke(this, new UriAddedEventArgs { Uri = uri });
}
}


ViewModel.cs:

public ViewModel(ISharingService sharingService)
{
sharingService.UriAdded += OnUriAdded;
}

public ObservableCollection<Uri> collection = new ObservableCollection<Uri>();

private async void OnUriAdded(object sender, UriAddedEventArgs args)
{
this.collection.Add(args.Uri));
}


The collection is bound to an element on the page, of course.

It appears I'm on a different thread when the event fires (no surprise there), but wrapping the operation in a

await Window.Current.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, ...)


doesn't change anything, I still get that exception. Has anybody got a clue what is going on here?

Edit:

For what it's worth, I tried to compile with the .NET native tool chain and spotted this warning:


Warning : DEP0810 : This app references Microsoft.NET.Native.Runtime.1.1, version 1.1.23231.0, found in your SDK, but you have a higher version of Microsoft.NET.Native.Runtime.1.1 installed on the target machine, 1.1.23406.0. If you continue to run this application, it will run against the currently installed version, Microsoft.NET.Native.Runtime.1.1, version 1.1.23406.0. Consider updating your SDK to match the version of Microsoft.NET.Native.Runtime.1.1 that is installed.


So yeah, I'm beginning to suspect some version conflict here. I have the latest Windows 10 SDK installed (
10.0.26624.0
) so I'm unsure how to update my SDK as suggested in the above warning.

Answer

I don't have a great answer - BUT i do know what is going on. Each window (your main application and your share window) have unique dispatchers.

You can not reference UI or dispatchers from one window to another window directly.

It is possible to invoke background thread and then call the main window dispatcher.

BUT my advice is to get rid of threading as much as possible in the share experience. I'm not sure how to globally get the dispatcher of the share window.