如何在。net中安全地运行异步代码和事件,以便VB6能够处理它?

时间:2022-02-08 16:32:19

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.

我有一些VB6代码需要慢慢地转移到。net。其中一些需要调用web。我正在从。net dll进行web调用,当它完成时,它会触发一个事件。我在VB6中处理事件。现在,这在我的测试机器上和大多数用户的机器上都很正常,但是当事件被触发时,一些用户会在某个时间内得到一个一致的程序崩溃。

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.

我认为这是一个线程问题。那么我应该如何处理。net端的线程呢?当调用。net代码时没有同步上下文,我认为这可能是问题所在。如何将异步操作返回到VB6调用线程?我的VB6代码是STA,我读到东西会自动通过COM封送到VB6线程,但这可能是错误的吗?如果确实是线程问题,我不太明白该怎么做。

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

我还没能找到一个模式哪个电脑有崩溃问题哪个电脑没有。

1 个解决方案

#1


2  

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.

所以后来我发现我被误导了,除了一些开发人员的机器外,几乎所有用户的机器都不能正常工作。问题是。tlb文件没有被生成和注册。

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. 您可以将它返回到主线程,可能通过表单的SynchronizationContext。
  3. 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.
  4. 您可以从任何线程中触发事件,并让它自动返回到VB6的STA线程,但是如果您只是注册了没有tlb选项的DLL,它就需要额外的tlb信息。如果不通过设置SynchronizationContext的任何UI线程,那么这个选项是很好的。

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

注意,如果您正在使用无regfree COM,那么选项2需要在程序集清单中使用comInterfaceExternalProxyStub元素。请看这里的问题和答案

#1


2  

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.

所以后来我发现我被误导了,除了一些开发人员的机器外,几乎所有用户的机器都不能正常工作。问题是。tlb文件没有被生成和注册。

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. 您可以将它返回到主线程,可能通过表单的SynchronizationContext。
  3. 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.
  4. 您可以从任何线程中触发事件,并让它自动返回到VB6的STA线程,但是如果您只是注册了没有tlb选项的DLL,它就需要额外的tlb信息。如果不通过设置SynchronizationContext的任何UI线程,那么这个选项是很好的。

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

注意,如果您正在使用无regfree COM,那么选项2需要在程序集清单中使用comInterfaceExternalProxyStub元素。请看这里的问题和答案