現在、namedpipeとC#を使用してネットワークプログラムを実装しています。サーバープログラムのmainメソッド内で、クライアントプログラムからメッセージを読み取る「ReadingMessage」という名前のスレッドを開始しました。このスレッドでは、クライアントから返されたメッセージに基づいて、コントロールのプロパティ(テキストボックスのテキスト、ラベルの位置など)を変更する必要があります。したがって、この手順ではクロススレッドエラーが発生しました(「UIスレッド間のReadingMesssage」)。この問題を解決するには2つの方法があることがわかりました
- Delegateを使用してコントロールを呼び出します
- Form.CheckForIllegalCrossThreadCalls = false;
両方をテストしましたが、問題が1つあります。フォームが最初に開始されたとき、コントロールのプロパティはエラーなしで変更されます。フォームを閉じて2回目に再開しても、コントロールのプロパティは変更されず、エラーメッセージも表示されません。コントロールのプロパティを変更するように指示されているコードへのブレークポイントをキャッチします。コードはスムーズに実行されますが、それでも問題は発生します。
何が問題なのかわかりません。したがって、誰かがこの問題を知っているなら、私に提案してください...
更新:(コードの投稿と私の最初の質問のいくつかのエラーの修正)
スレッドはサーバープログラムのメインメソッドにありません。質問を簡単に説明したかったので、私は間違っていました。ここで、私の質問について詳しく説明します。サーバープログラムのメインフォームには、ボタンクリックイベントが1つあります。
//Main Form
public partial class MainForm : Form
{
private void btnButton_Click(object sender, EventArgs e)
{
AnotherForm aform = new AnotherForm(); //This is the form where threading run
aform.show();
}
}
//AnotherForm
public partial class AnotherForm : Form
{
private void CargoLoading_Load(object sender, EventArgs e)
{
(new System.Threading.Thread(readingMessage)).Start(myPipe);
}
}
private void readingMessage(Object myPipeObject) //Read the messages send from the client machine
{
while (true)
{
//Code of serverstream
SetTextofTextBox1("AnyText"); //Code where the properties of control are instructed to change
}
}
private void SetTextofTextBox1(string text)
{
if (this.txtTextBox1.InvokeRequired) //the debugger return false at second time of this form is opened
{
SetTextCallback d = new SetTextCallback(SetTextofTextBox1);
this.Invoke(d, new object[] { text });
}
else
{
this.txtTextBox1.Text = text;
this.txtTextBox1.Update();
}
}
問題が発生するコードはこれだけです。「AnotherForm」を初めて開いたときはOKです。ただし、2回目に再度開かれると、コントロールのプロパティ(TextBox1のテキスト)は影響を受けず、変更されません。そこで、デバッガーControl.InvokeRequired
がこの2回目にfalseを返すことに気づきました。私はプログラマーとしての初心者なので、長い質問をして本当に申し訳ありません。
まだあなたの提案を期待しています...
アップデート2:
最後に私はすべての方法を試しましたが、それは最善の解決策にはなりません。したがって、この状況を回避し、私のような状況に遭遇したときに、コードの一部を別の概念で書き直すことをすべての人に提案したいと思います。