0

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 は、もう 1 つの小さなユーザー コントロールです。誰かこれの解決策を教えてください。

4

2 に答える 2

2

.Net 4.5 を使用している場合は、async/awaitを使用するのが最も簡単な解決策です。Invokeそうすれば、 sは必要ありません

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 "------";
}
于 2013-09-09T18:27:19.643 に答える