2 个 Winform 应用程序引用的托管 DLL。 Winform 1 启动 Winform 2,但上下文是共享的,除非两者分别执行

Managed DLL referenced by 2 Winform apps. Winform 1 launches Winform 2, but context is shared unless both are executed separately

我有两个 WinForm 客户端应用程序,它们引用同一个托管 DLL(用 C++/CLI 编写),目的是连接到本机套接字服务器。

两个 Winform 应用程序 运行 单独启动时都很好,但一个启动另一个时就不行了。

假设客户端 Winform 1 已启动。它按预期创建自己的套接字和上下文,然后继续将 Winform 2 作为单独的线程启动。

Winform 2也会打开自己的socket作为native server的client,但是当Winform 2关闭它的socket并退出时,Winform 1停止工作,因为它似乎认为它是Winform 2。所以WinForm的任何服务器请求1 失败,因为它的套接字变成了先前由套接字 2 关闭的套接字。

这种行为对我来说是新的,但显然它必须超出变量 "SOCKET socket_id"。

Winform 2 是否应该作为单独的进程而不是执行 Application.Run(Winform2) 的典型线程启动?

谢谢。

private void LaunchWinForm2Button_Click(object sender, EventArgs e)
{
     System.Threading.Thread myThread = 
         new System.Threading.Thread(new System.Threading.ThreadStart(StartWinForm2));

     myThread.Start(); 
}

private void StartWinForm2()
{
        CSharpFormApp.WinForm2 theWinForm2 = new CSharpFormApp.WinForm2();
        Application.Run(theWinForm2);

}

问题出在 C++/CLI DLL 中指向本机数据的全局指针。 由于 WinForms 通过多个 C++/CLI 接口获取数据,最初让它们通过全局指针访问本机数据更容易。

NativeLayer::NativeLayerData* native_data;


public ref class Test1Implementer : ITest1
{
     virtual bool TestConnect()
     {
        bool success = native_data->Connect();
        return success;
     }
};

public ref class Test2Implementer : ITest2
{
     virtual bool TestDisconnect()
     {
        bool success = native_data->Disconnect();
        return success;
     }
};

最终,这样的实现会再次困扰我,但这些都是尝试在工业应用程序中使用全局变量的危险。

一旦我摆脱了指向本机数据的托管全局指针,一切都会按预期进行。这是允许使用嵌套接口进行多线程处理的可能解决方案:

public ref class TestsImplementer : ITests 
{
private:
    NativeLayer::NativeLayerData* native_data;

public:
      TestsImplementer()
      {
         native_data = new NativeLayer::NativeLayerData();
      }

      ref class Test1Implementer : ITest1
      {
         virtual bool TestConnect(TestsImplementer^ tests)
         {
            bool success = tests->native_data->Connect();
            return success;
         }
      };

      ref class Test2Implementer : ITest2
      {
         virtual bool TestDisconnect(TestsImplementer^ tests)
         {
            bool success = tests->native_data->Disconnect();
            return success;
         }
      };
};