Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I safely run async code and events in .NET so VB6 can handle it?

Tags:

I have some VB6 code I need to slowly move over to .NET. Some of this requires calls to the web. I'm doing the web call from a .NET dll, and when it's done, it fires an event. I handle the event in VB6. Now this works fine on my test machine, and the majority of user's machines, but some users get a consistent crash of the program sometime around when the event is fired.

I'm thinking this is a threading issue. So how should I be handling threads on the .NET side of things? There is no synchronization context when the .NET code is called and I think that might be the issue. How would I get an async operation back to the VB6 calling thread? My VB6 code is STA and I read that things would be marshaled to the VB6 thread through COM automatically, but maybe that was wrong? I don't fully understand what to do if it's indeed a threading issue.

I haven't been able to find a pattern to which computers have the crash issue and which ones don't.

like image 975
Ben Zuill-Smith Avatar asked Jul 20 '16 20:07

Ben Zuill-Smith


1 Answers

So I found later that I was misinformed and it was not working on pretty much all user's machines except a few developer's machines. The issue was the .tlb file was not being generated and registered.

It seems that if you fire events from the main thread, everything is fine. But if you fire events asynchronously there are only two ways you can make it work without crashing:

  1. You can bring it back to the main thread, perhaps via a SynchronizationContext from a form.
  2. You can fire the event from any thread and let it get marshalled back to VB6's STA thread automatically, BUT it requires extra tlb information that isn't in the registry if you just register the DLL without the tlb option. This option is nice if you don't go through any UI thread that sets a SynchronizationContext.

Note that if you are using reg-free COM, option 2 requires the comInterfaceExternalProxyStub element in your assembly's manifest. See the question and answer here for an example of that

like image 173
Ben Zuill-Smith Avatar answered Sep 28 '22 04:09

Ben Zuill-Smith