多线程代码卡在Form.ShowDialog()语句上。

3

我刚开始学习C#,正在尝试编写一个测试网络连接的表单。我的想法是将连接部分放在线程中,在连接期间显示进度对话框。以下是我的代码:

Form_TestingConnection testingConnection = new Form_TestingConnection();
Thread t1 = new Thread(TestConnection);

try
{
testingConnection.ShowDialog();
t1.Start();    
}
catch (Exception ex)
{
    Logger.Error(ex);
if (MessageBox.Show(
    Resources.message_connection_issue,
    Resources.title_connection_issue,
    MessageBoxButtons.OK, MessageBoxIcon.Error) == DialogResult.OK)
{
    loginSuccessful = false;
}
}

TestConnection是一种测试连接并根据结果设置静态成员变量loginSuccessful的方法。我现在遇到的问题是代码卡在了testingConnection.ShowDialog()上。每当执行到这个地方时,它就不再前进了。有什么建议吗?非常感谢。


也许你想把线程移到testingConnection表单中,并在Form_Load事件中启动它? - Raghu
2个回答

4

ShowDialog方法以模态显示窗体。这意味着该窗体将显示,其他所有窗体都将被禁用,并且ShowDialog函数直到模态对话框关闭后才返回。

请改用Show方法。这将以非模态方式显示窗体。当您这样做时,Show函数立即返回,而窗体则保持打开状态。

你可以把ShowDialog看作是同步的,而Show则是异步的。

请确保在需要更新窗体上进度的线程中调用的任何方法都使用InvokeBeginInvoke来确保它们在主UI线程的上下文中运行。

最后,您当前的代码并不会等待线程完成其工作。try/catch块仅包装了窗体显示和线程执行的开始(t1.Start())。当您在线程上调用Start时,该调用会异步返回,线程会继续执行其工作。我不太确定您的代码尝试做什么,但我猜想catch块应该在线程内部。


谢谢David!你的回答很有道理。这让我困惑了好几个小时。 - Robert Kang

0
如果您正在尝试从另一个线程访问属于某个线程的任何GUI组件,则应使用InvokeRequired来避免跨线程异常。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接