2

私はスレッドの操作にかなり慣れていません。の値を設定しようとしていましたDependencyProperty:

    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));

セッターで SendOrPostCallback を使用する必要があるという難しい方法に気付きました (メソッドを呼び出すときに引数を提供するため)。アクションでは機能しません(引数が欠落しているためです。そして、wpfは実際にはそれについての雌犬であり、「ソースが利用できません」でTargetParameterCountExceptionの原因をデバッグして見つけ、手がかりがまったくありません.

SendOrPostCallback を使用する必要があるのはなぜですか? この場合、これが正しいものであることをどのように知る必要がありますか? 実際にセッターを呼び出すと、次の方法で機能するためです。

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

コースの代わりに SendOrPostCallback を使用すると、TargetParameterCountException が発生します。

そのような一見矛盾しているように見えることは、ただの常識なのだろうか?少なくともSendOrPostCallback、Action、およびBeginInvokeをキーワードとしてグーグルで検索しても意味のある結果が得られなかったため、ここで少し迷っています。

4

1 に答える 1

7

関連する情報:

1.Dispatcher.BeginInvoke使用しているオーバーロードは次のとおりです。

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

method: Dispatcher イベント キューにプッシュされる1 つの引数を取るメソッドへのデリゲート。

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

public delegate void SendOrPostCallback(object state)

3. についてAction

public delegate void Action()

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

もちろん、必要に応じて、1 つの引数を取るAction<T>デリゲートを使用することもできます。

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

または、引数をとらないデリゲート型の引数を期待するの別のオーバーロードを使用して、クロージャで C# コンパイラに汚い仕事をさせることもできます。Dispatcher.BeginInvoke

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

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

(また、この回答は、関連するデリゲート署名についてのみ、スレッドセーフの問題を扱っていません。)

于 2010-11-30T15:31:23.567 に答える