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;
}
};
};
我有两个 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;
}
};
};