DispatcherOperations.Wait()
What happens if you call dispatcherOperation.Wait()
on an operation that has already completed? Also, the docs say that it returns a DispatcherOperationStatus
, but wouldn't that always be Completed
since it (supposedly) doesn't return until it's done?
I was trying to use it like this:
private void Update()
{
while (ops.Count > 0) ops.Dequeue().Wait();
}
public void Add(T item)
{
lock (sync)
{
if (dispatcher.CheckAccess())
{
list.Add(item);
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item));
}
else
{
ops.Enqueue(dispatcher.BeginInvoke(new Action<T>(Add), item));
}
}
}
I'm using this in WPF, so all the Add
operations have to occur on the UI thre开发者_运维百科ad, but I figured I could basically just queue them up without having to wait for it to switch threads, and then just call Update()
before any read operations to ensure that the list is up to date, but my program started hanging.
i think i know why it is hanging.
you should read through the docs on DispatcherOperation.Wait there is a warning about calling wait on the same thread that the operation has been dispatched too. So what could be happening is that there is a Operation pending on the event queue, but then you call Wait on that operation from the GUI Thread so because wait is blocking the operation will never be dispatched so you have just deadlocked the guithread.
What you could do if you wanted to be absolutely sure that there were no pending events would be to just look at the Status field of operations in the queue, you can remove any that are Completed and if there are any that are not completed you will simply have to try again later.
Though honestly you would probably be better off just not worrying about it and handling the Collectionchanged notifications instead, that way you will be informed exactly when new elements are there and you wont have to worry about pending actions at all.
精彩评论