Reputation: 1377
I do have a Form which is registered on an update event. There I check if invoke is required and process the update either directly or via BeginInvoke:
protected void CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
if (InvokeRequired)
{
BeginInvoke(new MethodInvoker(delegate { ProcessCollectionChanged(e); }));
return;
}
ProcessCollectionChanged(e);
}
BUT: this does not always work! I know the details - the handle is created, i did even check the internal code and all is sane, from the watch window:
System.Windows.Forms.SafeNativeMethods.GetCurrentThreadId() 3540 int
System.Windows.Forms.SafeNativeMethods.GetWindowThreadProcessId(new System.Runtime.InteropServices.HandleRef(this, Handle), out _); 3540 int
InvokeRequired false bool
IsHandleCreated true bool
and of course my call stack of proof:
MyApp.Forms.dll!MyApp.Forms.TreeViews.BaseDataObjectTreeList.CollectionChanged(object sender = {MyApp.Client.DataStore}, System.Collections.Specialized.NotifyCollectionChangedEventArgs e = {System.Collections.Specialized.NotifyCollectionChangedEventArgs}) Line 809 C#
MyApp.DataProvider.dll!MyApp.DataProvider.DataCache<MyApp.DataObject>.RaiseCollectionChanged(System.Collections.Specialized.NotifyCollectionChangedEventArgs eventArgs = {System.Collections.Specialized.NotifyCollectionChangedEventArgs}) Line 465 C#
MyApp.Client.dll!MyApp.Client.DataCache<MyApp.DataObject>.RaiseCollectionChanged(System.Collections.Specialized.NotifyCollectionChangedEventArgs eventArgs = {System.Collections.Specialized.NotifyCollectionChangedEventArgs}) Line 353 C#
MyApp.DataProvider.dll!MyApp.DataProvider.DataCache<MyApp.DataObject>.DataObjects_CollectionChanged(object sender = {My.Utils.ObservableDictionary<string, MyApp.DataObject>}, System.Collections.Specialized.NotifyCollectionChangedEventArgs e = {System.Collections.Specialized.NotifyCollectionChangedEventArgs}) Line 127 C#
My.Utils.dll!My.Utils.ObservableDictionary<string, MyApp.DataObject>.OnCollectionChanged(bool firePropertyChanged = false, System.Collections.Specialized.NotifyCollectionChangedAction action = Remove, System.Collections.IList changedItems = {System.Collections.Generic.KeyValuePair<string, MyApp.DataObject>[1]}) Line 618 C#
My.Utils.dll!My.Utils.ObservableDictionary<string, MyApp.DataObject>.EndUpdate.AnonymousMethod__5() Line 517 C#
My.Utils.dll!My.Utils.ObservableDictionary<string, MyApp.DataObject>.EndUpdate() Line 534 C#
My.Utils.dll!My.Utils.ObservableDictionary<string, MyApp.DataObject>.UpdateBatch.Dispose() Line 663 C#
MyApp.DataProvider.dll!MyApp.DataProvider.DataCache<MyApp.DataObject>.UpdateCache(System.Collections.Generic.IEnumerable<string> keys = {string[1]}, System.Collections.Specialized.NotifyCollectionChangedAction action = Remove) Line 700 C#
MyApp.Client.dll!MyApp.Client.DataCache<MyApp.DataObject>.UpdateCache(System.Collections.Generic.IEnumerable<string> keys = {string[1]}, System.Collections.Specialized.NotifyCollectionChangedAction action = Remove) Line 339 C#
MyApp.Client.dll!MyApp.Client.DataStore.UpdateCache(System.Collections.Generic.IEnumerable<string> keys = {string[1]}, System.Collections.Specialized.NotifyCollectionChangedAction action = Remove) Line 44 C#
MyApp.Client.dll!MyApp.Client.DataCache<MyApp.DataObject>.Update.AnonymousMethod__0() Line 683 C#
mscorlib.dll!System.Threading.Tasks.Task.Execute() Unknown
mscorlib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx) Unknown
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx) Unknown
mscorlib.dll!System.Threading.Tasks.Task.ExecuteWithThreadLocal(ref System.Threading.Tasks.Task currentTaskSlot = Id = 230, Status = Running, Method = "Void <Update>b__0()") Unknown
mscorlib.dll!System.Threading.Tasks.Task.ExecuteEntry(bool bPreventDoubleExecution) Unknown
mscorlib.dll!System.Threading.ThreadPoolWorkQueue.Dispatch() Unknown
I can reproduce it when I close my dialog more or less about the same time an update occurs. The dialog is already hidden, the update is received on an other thread. The task finds no need to BeginInvoke and Update the controls. Meanwhile the main thread goes on and disposes the form. Now an exception is raised in the task (which is magically swallowed to nowhere).
Upvotes: 0
Views: 191