Is there a variant of Control.BeginInvoke which works before/after the handle is destroyed?

人走茶凉 提交于 2019-12-23 12:36:11

问题


I have a control which displays the state of an underlying asynchronous object. The object raises events, which arrive at the form, where they are essentially queued and eventually called using BeginInvoke.

A problem arises when the control is disposed. Because things are happening asynchronously, meaning it is always possible that an event callback is queued during disposal, I sometimes get an InvalidOperationException (Invoke or BeginInvoke cannot be called on a control until the window handle has been created.).

This is not the behavior I want. I want the callback to execute even if the control has been disposed (even if that causes an exception in the callback; that's a far more useful exception to me!). I want to handle the disposed state behavior in each callback (usually just skip if disposed, but sometimes not [eg. one control logs events (optionally to a file) and I don't want to lose log data!].).

Is there a method that works the way I want? Can I write a non-brittle one myself?


回答1:


Try SynchronizationContext.Current instead. This has the Post and Send members which roughly map to BeginInvoke and Invoke on Control. These operations will continue to function so long as the UI thread is alive vs. a specific control.

The type SynchronizationContext is not specific to WinForms and solutions leveraging it will be portable to other frameworks such as WPF.

For example.

BeginInvoke Code

void OnButtonClicked() {
  DoBackgroundOperation(this); 
}

void DoBackgroundOperation(ISynchronizedInvoke invoke) {
  ThreadPool.QueueUserWorkItem(delegate { 
    ...
    delegate.BeginInovke(new MethodInvoker(this.BackgroundOperationComplete), null);
  });
}

SynchronizationContext code

void OnButtonClicked() {
  DoBackgroundOperation(SynchronizationContext.Current);
}

void DoBackgroundOperation(SynchronizationContext context) {
  ThreadPool.QueueUserWorkItem(delegate {
    ...
    context.Post(delegate { this.BackgroundOperationComplete() }, null);
  });
}


来源:https://stackoverflow.com/questions/4513761/is-there-a-variant-of-control-begininvoke-which-works-before-after-the-handle-is

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!