【问题标题】:FromCurrentSynchronizationContext block throwing nullreferenceexception on Windows Form closeFromCurrentSynchronizationContext 块在 Windows 窗体关闭时抛出 nullreferenceexception
【发布时间】:2014-03-26 11:05:11
【问题描述】:

我正在开发一个 Windows 窗体应用程序。以下是在按钮单击事件上执行的代码段。

var taskExecute= Task<Datatable>.Run(() =>
{
    return = GetDt(); // time consuming method 
})

.ContinueWith(task=>
{
   this.datagridVal.Datasource = task.Result;
}, TaskScheduler.FromCurrentSynchronizationContext());

这很好用。但是如果我启动线程然后立即单击表单的 cross(x) 按钮,那么下面的代码行会抛出 NullReferenceException(很可能是因为表单已经被释放,datagrid 控件也是如此)

this.datagridVal.Datasource = task.Result;

如果在线程运行时窗体关闭,我如何修改代码以使这段代码不会抛出任何异常?另外请建议是否有更好的方法来处理使用

的场景

【问题讨论】:

  • 嗯,NRE 很奇怪,这应该会生成 ObjectDisposedException。可能是 DGV 的怪癖。无论哪种方式,检查 datagridVal.IsDisposed 应该是一种解决方法。最好将表单的关闭与任何待处理任务的完成联锁起来。
  • GetDt() 正在执行查询以获取数据表形式的大量数据。我想要的是在单击关闭按钮后立即取消线程。但是由于 GetDt() 中没有循环,所以我不确定在单击关闭按钮时是否可以有适当的方法来取消线程。在这种形式中,当单击关闭按钮时,可以运行超过三分之一的类似类型(数据库数据获取)。单击关闭按钮时,我想取消所有线程。

标签: winforms .net-4.0 task-parallel-library


【解决方案1】:

如果问题确实来自于表单已被处理,那么您可以使用this.IsDisposed 处理它:

var taskExecute= Task<Datatable>.Run(() =>
{
    return = GetDt(); // time consuming method 
})

.ContinueWith(task=>
{
    if (!this.IsDisposed)
    {
        this.datagridVal.Datasource = task.Result;
    }
}, TaskScheduler.FromCurrentSynchronizationContext());

【讨论】:

    猜你喜欢
    • 2014-06-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-25
    相关资源
    最近更新 更多