在C#Winforms项目中,我有一个UserControl类,它将TcpClient作为私有成员。 当用户拖动或以其他方式调整UserControl的父类的大小时,TcpClient设置为null。当UserControl的父级开始最大化或最小化时,TcpClient不会设置为null。处理TcpClient的代码在单独的thead中运行。我还没有找到任何其他用户遇到此问题。
我尝试在UserControl的构造函数和析构函数上设置断点,但无济于事。代码如下所示:
public partial class IPCInterface: UserControl
{
private TcpClient aClient = null;
private bool IsRunning = true;
private Thread ShellThread = null;
// [SNIP]
private void MainLoop()
{
// The exception occurs in this function when resizing
try
{
// The exception is thrown here, aClient.Client.Get returns null -> nullreference exception
while (IsRunning && aClient.Client.Connected == true)
{
while (aClient.Client.Available > 0)
ShellInputOutputBox.Invoke(
(MethodInvoker)delegate ()
{
ShellInputOutputBox.Text += ReceiveString();
});
Thread.Sleep(100);
}
if(aClient.Client.Connected == true)
aClient.Client.Close();
}
catch(Exception e)
{
MessageBox.Show(e.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); // The exception occurs here when resizing
}
}
public IPCInterface(TcpClient IPCStream)
{
InitializeComponent();
aClient = IPCStream;
ShellThread = new Thread(() => MainLoop());
ShellThread.Start();
}
我知道为什么会发生这种情况。有人知道如何抵消插座的关闭吗?
其他信息:
UserControl本身位于选项卡界面内,该选项卡界面也位于选项卡界面中(我不是UX设计师......)。所有这些接口都锚定到其父级的外边缘,以便在用户调整主窗体大小时移动它们。
答案 0 :(得分:0)
我已经解决了这个问题。事实证明,这是一个对象所有权问题,结合winforms在调整表单大小时显然会触发垃圾收集这一事实。
代码中的其他地方我创建了UserControl使用的连接,如下所示:
public static TcpClient OpenSession(string ServerIp, int ServerPort)
{
cServerControl Result = new cServerControl(ServerIp, ServerPort);
Result.Connect();
// [SNIP]
return Result.TcpClient;
}
我认为C#的结论是,由于cServerControl是在一个线程中创建的,该线程与稍后将与TcpClient交互的线程分开,因此它可以安全地处理TcpClient。忽略TcpClient显式转移到新线程的事实。更改代码以返回cServerControl(并使用UserControl中的cServerControl而不是TcpClient)修复了该问题,因为cServerControl现在未标记为可处置。