我正在构建一个 WPF,它有一个在 sql server 中执行 sql 查询的按钮(该查询可能需要很长时间才能运行)。
我想使用 TPL 来做到这一点。
这段代码:
var result = Task.Factory.StartNew(() => { command.ExecuteNonQuery(); });
给出了这个例外:
ExecuteNonQuery 需要一个打开且可用的连接。连接的当前状态已关闭。
我想这是因为查询在不同的线程上运行并且不知道打开的连接。
我有两个问题:
1. 如何让新线程知道这个打开的连接?
2.解决此问题后,如何使窗口不因该查询而冻结。
Thanks
您必须在任务主体中创建并打开此命令的连接。要么不关闭任务外部的连接,我认为这就是您在这里所做的,但无法从您粘贴的一行代码中看出。
我个人会在任务主体内完成这一切。如果用户不需要的话,为什么他们必须等待您甚至获得连接/命令设置?此外,您的连接也有可能是共享实例,并且无法跨线程工作。
一旦将数据库工作放入任务中,默认情况下它将在线程池线程上执行,这将释放 WPF 调度程序线程以返回处理 UI 事件,从而防止“冻结”。您很可能希望在数据库任务完成后更新 UI,为此您只需添加一个延续任务,但为了能够从该延续任务操作 UI,您需要确保它被显式安排为在调度程序线程上运行。这是通过在调度延续时显式指定当前同步上下文的 TaskScheduler 来完成的。那看起来像这样:
Task backgroundDBTask = Task.Factory.StartNew(() =>
{
... DB work here ...
});
backgroundDBTask.ContinueWith((t) =>
{
... UI update work here ...
},
TaskScheduler.FromCurrentSynchronizationContext());
这里的神奇之处在于使用TaskScheduler::FromCurrentSynchronizationContext
方法,该方法将安排在当前调用的 Dispatcher 线程上执行的延续。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)