gpt4 book ai didi

c# - 奇数任务并行库 InvalidOperationException

转载 作者:太空宇宙 更新时间:2023-11-03 21:55:39 25 4
gpt4 key购买 nike

我有以下代码来构建从 SQL Server 中提取的高级数据结构,然后当该数据的检索完成时,我更新 UI。使用的代码是

private void BuildSelectedTreeViewSectionAsync(TreeNode selectedNode)
{
// Initialise.
SqlServer instance = null;
SqlServer.Database database = null;

// Build and expand the TreeNode.
Task task = null;
task = Task.Factory.StartNew(() => {
string[] tmpStrArr = selectedNode.Text.Split(' ');

string strDatabaseName = tmpStrArr[0];

instance = SqlServer.Instance(this.conn);

database = instance.GetDatabaseFromName(strDatabaseName);
}).ContinueWith(cont => {
instance.BuildTreeViewForSelectedDatabase(this.customTreeViewSql,
selectedNode, database);

selectedNode.Expand();

task.Dispose();
}, CancellationToken.None, TaskContinuationOptions.OnlyOnRanToCompletion,
this.MainUiScheduler);
}

这在我的主要开发机器上正常工作;也就是说,它完成了 database 的构建对象,然后继续更新 UI 并处理 task (任务对象)。

但是,我一直在另一台机器上做一些测试,我得到一个 InvalidOperationException ,这是由于 task.Dispose()task仍在 Running 中状态,而是延续cont除非任务已经完成,否则永远不应该开火。

抛出异常时,调试器中的代码如下所示:

enter image description here

I am aware that it almost always unneccessary to call Dispose on tasks .这个问题更多的是关于为什么这里会触发延续?**

最佳答案

原因很简单,你在调用Dispose在延续本身上,在第一个任务上

您的代码包括:

Task task = null;
var task = <task 1>.ContinueWith(t => {
/* task 2 */

task.Dispose();
});

在上面的代码中,task 等于 continuation(ContinueWith 不传回原来的 Task,它传递了 continuation)这就是你在闭包中捕获的内容'正在传递给 ContinueWith

您可以通过比较传递给 ContinueWith 方法的 Task 参数与 task 的引用来测试它:

Task task = null;
var task = <task 1>.ContinueWith(t => {
/* task 2 */
if (object.ReferenceEquals(t, task))
throw new InvalidOperationException("Trying to dispose of myself!");

task.Dispose();
});

为了处理第一个,您需要将其分解为两个 Task 变量并捕获第一个 Task,如下所示:

var task1 = <task 1>;
var task2 = task1.ContinueWith(t => {
// Dispose of task1 when done.
using (task1)
{
// Do task 2.
}
});

但是,因为 previous TaskContinueWith 方法中作为参数传递给您,所以您不需要捕获 task在闭包中,您可以简单地在作为参数传递给您的 Task 上调用 Dispose:

var task = <task 1>.ContinueWith(t => {
// t = task 1
// task = task 2
// Dispose of task 1 when done.
using (t)
{
// Do task 2.
}
});

关于c# - 奇数任务并行库 InvalidOperationException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12427963/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com