2

:シリーズの一部:C#:別のクラスのフォームメンバーへのアクセスC#の別のcsファイルからフォームオブジェクトにアクセスする方法


こんにちは、

アイデアは、TCPクライアントでパケットが送受信されたときにメモを使用してユーザーに通知することです。

いくつかの修正の後、最も適切な解決策はこれであるように思われました

    public string TextValue
    {
        set
        {
            this.Memo.Text += value + "\n";
        }
    }

それが呼ばれている方法です

    var form = Form.ActiveForm as Form1;
    if(form != null)
        form.TextValue = "Test asdasd";

ただし、安全でないスレッド呼び出しのため、コードを呼び出すと例外がスローされます。msdnで解決策を見つけました、そこで使用したメソッドを取得できないようです。

これは私のリメイクですが、機能しません。

    private void SetTextMemo(string txt)
    {
        if(this.Memo.InvokeRequired)
        {
            this.Invoke(SetTextMemo,txt); //error here
        }
        else
        {
            this.Memo.Text += txt + "\n";
        }
    }

エラー:

引数「1」:「メソッドグループ」から「System.Delegate」に変換できません

引数「2」:「文字列」から「オブジェクト[]」に変換できません

基本的に、Invokeを使用して別のスレッドからメモにアクセスしようとしています(または、おそらくメモにテキストを追加しようとしています)。これまで使用したことがないので、間違いを誤解している可能性があります。

4

4 に答える 4

11

簡単な方法は次のとおりです。

this.Invoke((MethodInvoker)delegate {
    this.Memo.Text += txt + "\n";
});

これは、匿名の方法を使用してインラインでジョブを実行します。別のスレッドにいることを期待しているので、Invokeを呼び出すだけでもかまいません。UIスレッドからでも安全です。

于 2009-04-04T17:30:43.553 に答える
1

C#3.0および3.5フレームワークを使用している場合は、次のことを試してください

if ( this.Memo.InvokeRequired ) {
  this.Invoke((Action)(() => SetTextMemo(txt)));
} 
于 2009-04-04T17:32:10.927 に答える
1

実装では、InvokeRequired プロパティの動作により無限に再帰が妨げられるため、メソッドが無限に再帰しないことを前提としています。この仮定は正しいと証明されるかもしれませんが、この可能性を完全に回避するために関数をコーディングしても問題はありません。これが私が提案するものです:

    private void SetMemo(string txt)
    {
        Memo.Text = txt;
    }

    private delegate void MemoSetter(string txt);

    public void ThreadSafeSet(string txt)
    {
        Invoke(new MemoSetter(SetMemo), txt);
    }
于 2009-04-04T17:41:50.873 に答える
0

以前はこのクロススレッドビジネスをすべて処理していましたが、最近はAOPを使用しました。この場合、UIスレッドで実行するメソッドを装飾するだけです。次に例を示します(PostSharpから):

public class FormsThreadAttribute : OnMethodInvocationAspect
{
  public override void OnInvocation(MethodInvocationEventArgs eventArgs)
  {
    Form f = (Form)eventArgs.Delegate.Target;
    if (f.InvokeRequired)
      f.Invoke(eventArgs.Delegate, eventArgs.GetArgumentArray());
    else
      eventArgs.Proceed();
  }
}
于 2009-04-04T17:32:57.477 に答える