有Control.BeginInvoke的变体后把手被破坏其中工程之前/? [英] Is there a variant of Control.BeginInvoke which works before/after the handle is destroyed?

查看:254
本文介绍了有Control.BeginInvoke的变体后把手被破坏其中工程之前/?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有其中显示一个基本同步对象的状态控制。对象引发事件,这在形式,在那里它们被基本上排队,并最终利用称为BeginInvoke的到达。

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.

在控制设置在问题出现了。由于事情发生异步,这意味着它始终是可能的事件回调处置过程中排队,我有时会得到一个InvalidOperationException(调用或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?

推荐答案

尝试 SynchronizationContext.Current 代替。这样做的发表发送的成员其中的大致的地图 BeginInvoke的调用控制。这些操作将继续发挥作用,只要在UI线程是活与一个特定的控制。

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.

类型的SynchronizationContext 不是针对WinForms和解决方案,利用它移植到其他框架,如WPF。

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

例如。

BeginInvoke的code

BeginInvoke Code

void OnButtonClicked() {
  DoBackgroundOperation(this); 
}

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

的SynchronizationContext code

SynchronizationContext code

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

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

这篇关于有Control.BeginInvoke的变体后把手被破坏其中工程之前/?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆