我对使用线程还很陌生。我试图设置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));

我意识到在setter中必须使用SendOrPostCallback的困难方式(因为它在调用方法时提供了一个参数)。它不能与Action一起使用(由于缺少参数。而且,wpf确实很棘手,它调试和查找TargetParameterCountException的原因是“没有可用的源”,根本没有任何线索。

为什么必须在那里使用SendOrPostCallback?我怎么知道在这种情况下这是正确的呢?因为实际上通过以下方法调用 setter :
Dispatcher.BeginInvoke((Action)(()=>State=States.Updating), null);

并使用SendOrPostCallback而不是类(class)会导致TargetParameterCountException。

只是想知道这样看似不一致的东西是否只是常识?至少在自从使用SendOrPostCallback,Action和BeginInvoke作为关键字搜索之后,感觉有点迷失了,没有任何有意义的结果。

最佳答案

相关信息:

1.您正在使用的 Dispatcher.BeginInvoke 的重载为:

public DispatcherOperation BeginInvoke(
    DispatcherPriority priority,
    Delegate method,
    Object arg
)
method:方法的委托(delegate),该方法接受一个参数,该参数被推送到Dispatcher事件队列中。

2. SendOrPostCallBack 委托(delegate)声明为:
public delegate void SendOrPostCallback(object state)

3.至于 Action :
public delegate void Action()

显然,SendOrPostCallBack委托(delegate)是兼容的,因为它只接受一个参数,而Action不接受,因为它是无参数的。

当然,如果您愿意,可以使用 Action<T> 委托(delegate),该委托(delegate)确实接受单个参数:
Dispatcher.BeginInvoke(DispatcherPriority.Background,
                        new Action<States>(arg => SetValue(StateProperty, arg)),
                        value);

另外,您可以使用Dispatcher.BeginInvokedifferent overload,它期望一个不带参数的委托(delegate)类型的参数,并让C#编译器在闭包中为您完成肮脏的工作:
Dispatcher.BeginInvoke(DispatcherPriority.Background,
                        new Action(() => SetValue(StateProperty, value));

注意value是一个捕获的变量,因此请小心。

(此外,此答案不涉及任何线程安全问题,仅涉及所涉及的委托(delegate)签名。)

关于c# - 多线程环境中SendOrPostCallback和Action之间的区别?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/4315161/

10-09 04:46