表单在第二次打开时冻结

本文关键字:冻结 第二次 表单 | 更新日期: 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;
        }));
    }
}

您可以展开代码,以检查表单是否仍然有效。