Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 是否存在Control.BeginInvoke的变体,该变体在销毁句柄之前/之后工作?_.net_Winforms_Asynchronous_Controls_Begininvoke - Fatal编程技术网

.net 是否存在Control.BeginInvoke的变体,该变体在销毁句柄之前/之后工作?

.net 是否存在Control.BeginInvoke的变体,该变体在销毁句柄之前/之后工作?,.net,winforms,asynchronous,controls,begininvoke,.net,Winforms,Asynchronous,Controls,Begininvoke,我有一个显示底层异步对象状态的控件。该对象引发事件,这些事件到达表单,在表单中它们基本上排队并最终使用BeginInvoke调用 处置控件时会出现问题。因为事情是异步发生的,这意味着在处理过程中总是可能有事件回调排队,所以有时会出现InvalidOperationException(在创建窗口句柄之前,不能对控件调用Invoke或BeginInvoke) 这不是我想要的行为。我希望即使控件已被释放,也能执行回调(即使这会导致回调中出现异常;这对我来说是一个更有用的异常!)。我希望处理每个回调中的

我有一个显示底层异步对象状态的控件。该对象引发事件,这些事件到达表单,在表单中它们基本上排队并最终使用BeginInvoke调用

处置控件时会出现问题。因为事情是异步发生的,这意味着在处理过程中总是可能有事件回调排队,所以有时会出现InvalidOperationException(在创建窗口句柄之前,不能对控件调用Invoke或BeginInvoke)

这不是我想要的行为。我希望即使控件已被释放,也能执行回调(即使这会导致回调中出现异常;这对我来说是一个更有用的异常!)。我希望处理每个回调中的已释放状态行为(如果已释放,通常只跳过,但有时不跳过[例如,一个控件记录事件(可选地记录到文件),我不希望丢失日志数据!]


有没有一种方法可以按照我想要的方式工作?我可以自己写一个非脆性的吗?

试试同步上下文。当前的。这有
Post
Send
成员,它们大致映射到
Control
上的
BeginInvoke
Invoke
。只要UI线程与特定控件处于活动状态,这些操作将继续运行

SynchronizationContext类型不特定于WinForms,利用它的解决方案将可移植到其他框架,如WPF

比如说

BeginInvoke代码

void OnButtonClicked() {
  DoBackgroundOperation(this); 
}

void DoBackgroundOperation(ISynchronizedInvoke invoke) {
  ThreadPool.QueueUserWorkItem(delegate { 
    ...
    delegate.BeginInovke(new MethodInvoker(this.BackgroundOperationComplete), null);
  });
}
同步上下文代码

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

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

你能举个用法的例子吗?它是控制中心的成员还是全球性的东西?谢谢,这真的很有用。如果句柄不存在,我不太清楚如何获取控件和它的同步上下文。