我对使用线程还很陌生。我试图设置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.BeginInvoke
的different overload,它期望一个不带参数的委托(delegate)类型的参数,并让C#编译器在闭包中为您完成肮脏的工作:Dispatcher.BeginInvoke(DispatcherPriority.Background,
new Action(() => SetValue(StateProperty, value));
注意
value
是一个捕获的变量,因此请小心。(此外,此答案不涉及任何线程安全问题,仅涉及所涉及的委托(delegate)签名。)
关于c# - 多线程环境中SendOrPostCallback和Action之间的区别?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/4315161/