我正在构建一个WPF,它有一个在sql server中执行sql查询的按钮(查询可能需要很长时间才能运行) . 我想使用TPL来做到这一点 .
此代码:var result = Task.Factory.StartNew(()=> {command.ExecuteNonQuery();});
给出了这个异常:ExecuteNonQuery需要一个开放且可用的连接 . 连接的当前状态已关闭 .
我想这是因为查询在不同的线程上运行而且不知道打开的连接 .
我有两个问题:1 . 如何让新线程知道这个开放连接? 2.解决此问题后,如何通过此查询使窗口不冻结 .
谢谢
2 回答
您必须在Task的正文中创建并打开此命令的连接 . 要么关闭或不关闭任务外部的连接,我认为这是你在这里做的,但无法从你粘贴的一行代码中分辨出来 .
我个人会在Task团体中亲自完成这一切 . 为什么用户必须等待你甚至不必进行连接/命令设置?此外,您连接的可能性是共享实例,并且无法跨线程工作 .
一旦你将数据库工作变成一个任务,它将默认在线程池线程上执行,这将释放WPF调度程序线程以返回处理UI事件,防止“冻结” . 最有可能的是,您需要在完成数据库任务后更新UI,为此您需要添加延续任务,但为了能够从该延续任务中操作UI,您需要确保将其明确安排到在Dispatcher线程上运行 . 这是通过在调度延续时显式指定当前同步上下文的TaskScheduler来完成的 . 这看起来像这样:
这里的神奇之处在于使用
TaskScheduler::FromCurrentSynchronizationContext
方法,该方法将调度继续在当前调用的Dispatcher线程上执行 .除了 @Drew Marsh 答案,
To avoid Exception:
You can use check for Synchronization Content Exists:
而是使用它: