使用来自任务线程的数据进行故障

时间:2013-07-23 09:39:28

标签: vb.net task-parallel-library

我有一种方法可以为每个产品收集各种文件。我想让该方法异步,因为它从其他网站下载文件。我做了这个代码:

For Each product In productList
    If model.Sds Then
        Dim sdsTask As Task(Of ZipFile) = Task(Of ZipFile).Factory.StartNew(Function() GetSafetyDataSheets(product.Product))
        sdsTask.ContinueWith(Sub(t)
                                 product.SDS = t.Result
                                 Debug.WriteLine("test")
                             End Sub, TaskContinuationOptions.OnlyOnRanToCompletion)
        taskList.Add(sdsTask)
    End If
    If model.Apb Then
        Dim apbTask As Task(Of List(Of ZipFile)) = Task(Of List(Of ZipFile)).Factory.StartNew(Function() GetAPB(product.Product, model.Department))
        apbTask.ContinueWith(Sub(t) product.Instruction = t.Result)
        taskList.Add(apbTask)
    End If
    If model.Pdb Then
        Dim pdbTask As Task(Of ZipFile) = Task(Of ZipFile).Factory.StartNew(Function() GetProductDatasheet(product.Product))
        pdbTask.ContinueWith(Sub(t) product.PDB = t.Result)
        taskList.Add(pdbTask)
    End If


Next

Task.WaitAll(taskList.ToArray)

但是当它等待并且我试图访问我的产品列表中的产品中的SDS,APB或PDB时,它们只是空对象。我可以看到我的“getter”方法返回正常,但数据从未进入product.SDS属性等。

2 个答案:

答案 0 :(得分:1)

ContinueWith不会修改现有任务,而是返回一个新任务,该任务将在延续完成后完成。您正在等待原始任务(例如apbTask),您应该在等待ContinueWith来电的结果。

答案 1 :(得分:1)

您的代码尝试更新对已更改的产品的引用。当延续运行时,product指向的实例是外部product变量当时具有的值。它可能是列表中的最后一个产品,也可能是任何其他产品。

这不是一个bug,而是外部变量捕获与lambdas一起使用的方式。

不是尝试访问外部变量,而是将其值作为状态值传递给TaskFactory.StartNew(Action(Of Object),Object)

对ContinueWith的调用也是如此。如果要修改上一步中使用的产品,则应将其作为结果的一部分传递给下一步,也许使用Tuple来执行此操作。