简体   繁体   English

Dispatcher.BeginInvoke c#,silverlight

[英]Dispatcher.BeginInvoke c#, silverlight

In Silverlight, to marshall a call to the UI thread we are supposed to use this.Dispatcher.BeginInvoke((ThreadStart)delegate(){}) . 在Silverlight中,要编组对UI线程的调用,我们应该使用this.Dispatcher.BeginInvoke((ThreadStart)delegate(){})

My question is if multiple threads call a function which does this then do those calls get queued up and execute one after another? 我的问题是,如果多个线程调用一个执行此操作的函数,那么这些调用是否排队并一个接一个地执行? If yes, then can I safely assume that even though the function is getting called from multiple threads, the code inside the this.Dispatcher.BeginInvoke((ThreadStart)delegate(){} ); 如果是,那么我可以安全地假设即使函数是从多个线程调用的, this.Dispatcher.BeginInvoke((ThreadStart)delegate(){} );的代码也是this.Dispatcher.BeginInvoke((ThreadStart)delegate(){} ); is thread safe ? 线程安全吗?

Code is thread-safe when it has no state, doesn't modify state that can be shared across thread boundaries or modifies state in a controlled manner that all users of that state share in order to ensure thread safety (such as locks). 代码在没有状态时是线程安全的,不修改可以跨线程边界共享的状态,或者以受控方式修改状态,使该状态的所有用户共享以确保线程安全(例如锁)。

Therefore, there is no guarantee of thread safety from Dispatcher.BeginInvoke . 因此, Dispatcher.BeginInvoke无法保证线程安全。 That said, it is guaranteed that the delegates will all execute on the same thread (the UI thread) so you can assume that the delegates will not run concurrently. 也就是说,保证代理将在同一个线程(UI线程)上执行,因此您可以假设代理不会同时运行。 This does not mean they are inherently thread-safe - that depends on what you do in those delegates - but if you don't spin or interact with other threads from those delegates or methods called by those delegates, you can assume thread-safety. 这并不意味着它们本身就是线程安全的 - 这取决于你在这些委托中做了什么 - 但是如果你不旋转或与那些委托调用的那些委托或方法中的其他线程交互,你可以假设线程安全。

Your code snippets are a bit misleading because of the use of the (ThreadStart) delegate type. 由于使用了(ThreadStart)委托类型,您的代码片段有点误导。 The important thing to know is that in any STA Threaded environment there is exactly one thread blessed to be the "UI" thread. 需要知道的重要一点是,在任何STA Threaded环境中,只有一个线程可以成为“UI”线程。 All UI objects need to be created and interacted with on that thread. 需要在该线程上创建并交互所有UI对象。

So the Dispatcher is used for several things the most easy to understand usage is to use it from a background thread to put what you're calling back onto the UI thread. 所以Dispatcher用于几个最容易理解的用法是从后台线程使用它来将你正在调用的东西放回UI线程。 So what you put in there isn't exactly "thread safe" but it is guaranteed to be called on the UI thread. 所以你放在那里的并不是“线程安全”,但保证在UI线程上调用它。 If you put everything you do onto the UI thread it will be called, one after another, not at the same time. 如果你将你所做的一切都放到UI线程上,它将被一个接一个地调用,而不是同时调用。

BeginInvoke is an asynchronous call to put a delegate on the UI thread queue while Invoke is a syncrhonous call. BeginInvoke是一个异步调用,用于将委托放在UI线程队列上,而Invoke是一个同步调用。 What's really mind boggling is that you can actually call Invoke from the UI thread which will block, put your delegate onto the queue and yield to the next items in the queue, eventually calling what it just Invoke'd. 令人难以置信的是,您实际上可以从UI线程调用Invoke,它将阻塞,将您的委托放入队列并屈服于队列中的下一个项目,最终调用它刚刚调用的内容。

Another important thing to keep in mind is that the Dispatcher is actually a Prioritized queue. 要记住的另一个重要事项是Dispatcher实际上是一个优先级队列。 So it's not a pure queue in the sense of first-in-first-out because where you are inserted into the queue is based on your priority and it's entirely possible for enough things to be jammed into the queue that your invoked method never gets executed. 因此,在先进先出的意义上,它不是纯队列,因为您插入队列的位置取决于您的优先级,并且完全有可能将足够的东西塞进队列中,您的调用方法永远不会被执行。

Yes, these calls get queued up. 是的,这些电话排队等候。 Calls to BeginInvoke are thread-safe (you can call this method from any thread at any time), and all calls marshaled to the UI thread all run single threaded. BeginInvoke调用是线程安全的(您可以随时从任何线程调用此方法),并且所有调用到UI线程的调用都运行单线程。 Because there is only one UI thread. 因为只有一个UI线程。 Because. 因为。

In general, yes, you are correct that each delegate gets added to the queue to await processing by the Dispatcher thread. 通常,是的,您是正确的,每个委托都被添加到队列中以等待Dispatcher线程的处理。

I'm not sure if there is any current or future guarantee on ordering on the invocation of the delegate from the Dispatcher.BeginInvoke() calls - but I do know that currently the ordering seems to be preserved. 我不确定从Dispatcher.BeginInvoke()调用调用委托时是否有任何当前或未来的保证 - 但我知道目前的顺序似乎被保留了。

Regardless of this though - yes, it is safe to assume that there will be only Dispatcher (UI) thread - so multiple delegates won't be invoked at the same time. 尽管如此 - 是的,可以安全地假设只有Dispatcher(UI)线程 - 因此不会同时调用多个委托。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM