2010-11-30 7 views
1

私はスレッドで作業するのはかなり新しいです。私はセッターにあなたが(メソッドを呼び出すときには、引数を提供して)SendOrPostCallbackを使用する必要があること、ハードな方法を実現マルチスレッド環境でSendOrPostCallbackとActionの違いはありますか?

public States State 
    { 
     get { return (States)GetValue(StateProperty); } 
     set 
     { 
      Dispatcher.BeginInvoke(DispatcherPriority.Background, 
       //(SendOrPostCallback)delegate { SetValue(StateProperty, value); }, //works 
       (Action)(()=> SetValue(StateProperty, value)), //doesnt 
       value); 
     } 
    } 
    public static readonly DependencyProperty StateProperty = 
     DependencyProperty.Register("State", typeof(States), typeof(FTPDownload), new UIPropertyMetadata(States.Idle)); 

:私はDependencyPropertyの値を設定しようとしていました。それはActionで動作しません(引数がないためwpfは実際には問題です、デバッグし、 "ソースが利用できません"と何も手がかりがない)。

なぜ私はそこSendOrPostCallbackを使用する必要があり、どのように私は実際にセッターを呼び出すと経由して動作するので、この場合には、これは正しいものであることを知っている必要があります。??

Dispatcher.BeginInvoke((Action)(()=>State=States.Updating), null); 

とSendOrPostCallbackの代わりTargetParameterCountExceptionでコースの結果を使用して..

一見矛盾しているようなものがちょうど普通のk今?ここでは、少なくともSendOrPostCallback、Action、BeginInvokeをキーワードとして検索して以来、ここで少し失われていると感じても意味のある結果は得られませんでした。情報の

+1

FYI、国家のためのセッターが_not called_がある更新はデータの結果として発生した場合結合システム。 SetValueが直接呼び出されます。そのため、この同期手法は期待どおりに機能しない可能性があります。一般的なベストプラクティスは、すべてのDPアップデートがUIスレッドで発生していることを確認することです。これは、UIロジック(ViewModel)を、基礎となるデータおよびロジック(Model)で行われているマルチスレッドワークから分離することを意味します。 –

答えて

6

関連作品:あなたが使用しているDispatcher.BeginInvoke

1.過負荷がある:

public DispatcherOperation BeginInvoke(
    DispatcherPriority priority, 
    Delegate method, 
    Object arg 
) 

method:プッシュされる1つの引数を取る方法にデリゲート、 Dispatcherイベント・キューに入れます。

2. SendOrPostCallBackデリゲートは次のように宣言されています

Actionため
public delegate void SendOrPostCallback(object state) 

3.As:

public delegate void Action() 

それは単一の引数を取りますが、Actionではないので、明らかにSendOrPostCallBackデリゲートは互換性がありますこれはパラメータがないためです。もちろん

、あなたが好みならは、単一の引数を取るんAction<T>デリゲート、使用することができます。また

Dispatcher.BeginInvoke(DispatcherPriority.Background, 
         new Action<States>(arg => SetValue(StateProperty, arg)), 
         value); 

を、あなたがある引数を期待Dispatcher.BeginInvokedifferent overloadを使用することができますが引数を取らず、かつ閉鎖であなたのために汚い仕事をするためにC#コンパイラを取得し、デリゲート型:

Dispatcher.BeginInvoke(DispatcherPriority.Background, 
         new Action(() => SetValue(StateProperty, value)); 

valueはキャプチャされた変数であることに注意してください。

(また、この答えは関与デリゲート署名について、任意のスレッド安全性の問題に対処しません。)

+0

地獄、私はばかです。もちろん一方のメソッドは引数をとり、もう一方のメソッドは引数をとりません。まあ、ありがとう。もし私が依存性メソッドでthread-safetyを置いて読んでいないのであれば、1分前には悪い習慣です;;)* sigh * – kris

関連する問題