2009-04-04 11 views
2

:シリーズの一部:C#: Accessing form members from another classおよびHow to access form objects from another cs file in C#C#の別のスレッドから呼び出したクラスメンバーへのアクセス


こんにちは、

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

は修正のカップルの後、最適なソリューションは、コードがあるため安全でないスレッドの、例外をスロー呼び出して、それはしかし
var form = Form.ActiveForm as Form1; 
    if(form != null) 
     form.TextValue = "Test asdasd"; 

と呼ばれています方法です。この1

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

ように見えました私は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.Iを使って別のスレッドからメモにアクセスしようとしています(またはメモにテキストを追加する)、私は間違いを誤解しています。

+0

イベントの使用はどうですか? – bytebender

答えて

11

簡単な方法がある:仕事をインラインで行うための匿名メソッドを使用しています

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

が別のスレッドにあると想定しているので、Invokeを呼び出すだけで、UIスレッドからも安全です。

+0

これは、Gravellが私のベーコンを保存してくれた2番目です(しかし、最後の時間ではありません)。ちょうどそのために、あなたはこの土曜日を休みにすることができます。私はあなたにも日曜日をあげることができると思います。 – Chris

1

あなたは、C#3.0と3.5のフレームワークを使用している場合、私はこのすべてのクロススレッドの業務を処理するために使用されるが、最近、私はあなたが単純にメソッドを飾るAOP、一緒に行った次

if (this.Memo.InvokeRequired) { 
    this.Invoke((Action)(() => SetTextMemo(txt))); 
} 
+0

そして.NET 3.5 for the Actionデリゲート型;-p –

+0

@Marc、私はそれが3.5型であることを忘れています。 2.0で追加されなかったのはなぜですか? – JaredPar

0

を試してみてくださいUIスレッドで実行します。ここでの例では、(PostSharpから)です:InvokeRequiredプロパティの動作は、それを防ぐことができますので、

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(); 
    } 
} 
+0

これは、他の方法のIMHOよりも前に必ずAOPを使用する必要がある場所です。しかしPostSharpやAOPに慣れていない人にとっては、あなたの投稿からどのように正確に機能するのか、その実際の使いやすさは何かを理解することは難しいかもしれません。 – Groo

+0

私はPostSharpに関連する教材へのリンクを提供したいと思いますが、実際には許可されていません:( –

1

あなたの実装では、メソッドが無限に再帰しないことを前提としています。この前提は真実であるかもしれませんが、この可能性を完全に回避する関数のコーディングには問題はありません。ここに私が提案するものがあります:

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

    private delegate void MemoSetter(string txt); 

    public void ThreadSafeSet(string txt) 
    { 
     Invoke(new MemoSetter(SetMemo), txt); 
    } 
関連する問題