我有一个程序需要连接到服务器来收集一些数据。我启动一个新线程并让它执行连接序列。按照这个顺序,它将继续尝试连接,直到成功为止。
连接顺序代码如下:
// Code for InitializeConnection
// Our address to our Authentication Server
IPEndPoint authenServerEP = new IPEndPoint(IPAddress.Parse("192.168.1.100"), 8007);
// Connect to the Authentication server
while (!this.connected)
{
try
{
this.sock.Connect(authenServerEP);
this.connected = true;
}
catch (SocketException retryConnectException)
{
if (false == retried)
{
retried = true;
}
}
}
启动线程后,在父/主线程中,我继续循环并检查主窗体/对话框中声明的变量是否已连接。
主线程代码如下:
// Connect to the Authentication Server
new Thread(InitializeConnection).Start();
// Loop till connected
while (!this.connected)
{
if ((true == this.retried) && (false == this.establishingConnectionForm.Visible))
{
this.establishingConnectionForm.Show();
}
}
this.establishingConnectionForm.Dispose();
如果在 InitilizeConnection 代码中它因第一次失败而重试连接,我希望它显示一个新的对话框/表单,让用户知道它正在重试连接。当我在建立ConnectionForm(在父线程中)上使用 .Show() 方法时,它会显示对话框/表单,但无法正确显示。表单上的一些工具呈白色阴影,鼠标图标变成思考/执行工作图标,并且不允许您单击表单并与其交互。
我想象的是,我将能够显示表单并与其交互(即通过在右上角“X”关闭它)并移动它等等。建立连接后,我将在主/父线程中打破 while(!this.connected) 循环,然后关闭/处置建立ConnectionForm。
我尝试在执行连接序列的线程上创建/初始化表单,但我仍然得到相同的结果,表单上的工具被遮蔽,并且无法与其交互。使用 .ShowDialog() 方法可以使其正确显示并让我与其交互,但我不想阻止,因为我没有 DialogResult。我希望表单在建立连接后自行关闭。
感谢您阅读我的帖子以及您的任何意见。 :D
最佳答案
您不能在 UI 线程中像这样循环,它将无法执行基本职责,例如绘制窗口和响应输入。不要使用 DoEvents(),当用户关闭主窗体时,这将使您的代码在没有任何用户界面的情况下运行。如果幸运的话,您将得到一个 ObjectDisposeException。
解决方案是让线程通知 UI 线程它在建立连接时遇到问题。您可以使用BackgroundWorker 的ReportProgress 事件干净地做到这一点。
关于c# - 对话框无法通过 .Show 正确显示,但又不想在 C# 中进行多线程处理时阻塞 .ShowDialog,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1911634/