表单在第二次打开时冻结
本文关键字:冻结 第二次 表单 | 更新日期: 2023-09-27 18:30:46
我正在开发一个访问WCF服务的Windows窗体应用程序。我遇到了一个很大的问题,我无法预测它的原因。甚至 Visual Studio 调试器也不会在"输出"视图中显示任何异常。场景是这样的,我有一个自定义用户控件,上面有一个linkLabel
。每当单击链接标签时,都会打开一个表单,并将类对象传递给它。此对象的类定义驻留在远程服务器上的 WCF 服务上。现在的问题是,当我单击 linkLabel
时,表单会根据传递给它的类对象完美地加载其每个组件。但是当我关闭此表单并再次单击该linkLabel
时,表单会打开,但在加载某些元素后立即冻结。我尝试了许多代码变体。编辑了我认为可能影响的许多代码部分。但他们都没有表现出差异。由于我不知道代码实际上在哪里出错,因此我正在发布单击后调用的linkLabel
单击代码和函数。
private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
Enabled = false;
string temp = Title.Text;
Title.Text = "Opening...";
System.Threading.Thread t = new System.Threading.Thread(new System.Threading.ThreadStart(openTopic));
t.Start();
Title.Text = temp;
Enabled = true;
}
void createTopicWindow()
{
TopicViewer t = new TopicViewer(t);
Invoke(new Action(() => t.Show()));
}
private void openTopic()
{
Invoke(new Action(() => createTopicWindow()));
}
以上是编辑后的代码,因为我之前Cross thread exception
过。
以下是单击linkLabel
时调用的窗体的构造函数的代码:
try
{
InitializeComponent();
this.t = topic;
if (IsHandleCreated == false)
CreateHandle();
System.Threading.Thread th = new System.Threading.Thread(new System.Threading.ThreadStart(loadTopic));
th.Start();
Common.openedTopics.Add(this);
AddComment addComment1 = new AddComment();
addComment1.Topic = t;
addComment1.Dock = DockStyle.Fill;
panel5.Controls.Add(addComment1);
backgroundWorker1.RunWorkerAsync();
}
catch (Exception)
{ }
void loadTopic()
{
Invoke(new Action(()=>tHead = new TopicHeader()));
Global.SetControlPropertyThreadSafe(tHead,"Topic", t);
Global.SetControlPropertyThreadSafe(tHead,"Dock", DockStyle.Fill);
Invoke(new Action(()=>panel1.Controls.Add(tHead)));
Global.SetControlPropertyThreadSafe(this,"Text", t.Title + " - Topic Viewer");
if (t.Description.Trim().Length > 0)
{
Global.SetControlPropertyThreadSafe(webBrowser1, "DocumentText", t.Description);
}
else
{
Invoke(new Action(() => tabControl1.TabPages[0].Dispose()));
}
Global.SetControlPropertyThreadSafe(tabPage2, "Text", "Comments (" + client.getComCount(t.TopicID) + ") ");
}
TopicHeader 是另一个小型用户控件。请谁告诉我解决这个问题的方法?
如果您使用的是 .Net 4.5,那么使用 async/await 将是最简单的解决方案。这样,您就不需要任何Invoke
async private void Form1_Load(object sender, EventArgs e)
{
string s = await Task<string>.Factory.StartNew(LongRunningTask,
TaskCreationOptions.LongRunning);
this.Text = s;
}
string LongRunningTask()
{
Thread.Sleep(10000);
return "------";
}
我不能直接回答你的问题,但这可能会让人坚持下去。
public void Form_Load()
{
// do some stuff on the gui-thread
// i need to do something that takes a long time:
ThreadPool.QueueUserWorkItem((state) =>
{
// i'll execute it on the ThreadPool
// Long running code....
// update results in mainform on gui thread.
Invoke(new Action( delegate
{
// because the invoke will execute this on the gui-thread, you'll able to update controls.
// update my gui controls.
DataGrid.Source = myReceiveDataThing;
}));
}
}
您可以展开代码,以检查表单是否仍然有效。