首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从Task的Continuation方法内的事件中移除委托

从Task的Continuation方法内的事件中移除委托
EN

Stack Overflow用户
提问于 2012-03-13 21:46:05
回答 1查看 657关注 0票数 1

我在一个父MDI窗体上有一个“停止进程按钮”ToolStripButton。从子窗体中,我使用TPL在后台线程上启动了一个进程,并获得任务返回状态并相应地更改UI。“停止进程按钮”的Click事件是使用delegate处理的,它工作得很好。然而,我似乎不能删除它。请参考下面的代码:

代码语言:javascript
复制
private void buttonRunValid_Click(object sender, EventArgs e)
{
    // UI.
    mainForm.stopButton.Enabled = true;

    // Thread cancellation.
    cancelSource = new CancellationTokenSource();
    token = cancelSource.Token;

    // Start new parallel task and pass uiScheduler.
    Task<bool> asyncValidationTask = new Task<bool>(state => 
        asyncRunValidationProcess(uiScheduler, token, ref timeSpan), 
            "Running Validation Process");
    asyncValidationTask.Start();

    // Callback for cancellation.
    asyncValidationTask.ContinueWith(task =>
    {
        // Do some error checking with task.Status...

        // Remove delegate (back on uiThread).
        mainForm.stopButton.Click -= delegate
            {
                UtilsTPL.CancelRunningProcess(ref mainForm, asyncValidationTask, cancelSource); 
            };
        return;
    }, TaskScheduler.FromCurrentSynchronizationContext());

    // Handle the cancellation.
    mainForm.stopButton.Click += delegate 
        { 
            UtilsTPL.CancelRunningProcess(ref mainForm, asyncValidationTask, cancelSource);
        };
    return;
}

其中mainFormMdiParentstopButtonmainFormToolStripButton的访问器,它触发取消/停止进程事件。

我正在尝试删除tasks continuation方法中的delegate,但这不起作用。我还尝试使用反射遍历ToolStripButton包含的所有事件:

代码语言:javascript
复制
FieldInfo fieldInfo = 
    typeof(Control).GetField("EventClick", BindingFlags.Static | BindingFlags.NonPublic); 
object obj = fieldInfo.GetValue(_stripButton); 
PropertyInfo propertyInfo = 
    _stripButton.GetType().GetProperty("Events", BindingFlags.NonPublic | BindingFlags.Instance); 
EventHandlerList list = (EventHandlerList)propertyInfo.GetValue(_stripButton, null); 
list.RemoveHandler(obj, list[obj]); 

这也不起作用。如何删除EventHandler/delegate

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-03-13 23:37:31

由于这个原因,使用匿名方法或lambdas作为事件处理程序是有问题的。您添加的委托和您尝试移除的委托是不同的实例(尽管包含相同的代码)。此问题的解决方案是保存对正在添加的委托的引用,或者使用命名方法。See this question获取详细信息。

但是,我想问的是,为什么首先要删除事件处理程序。如果是为了阻止处理程序代码在特定进程运行时运行,我倾向于禁用该按钮,然后在处理完成后重新启用它。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9685236

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档