0

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

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 属性等。

4

2 回答 2

1

ContinueWith不修改现有任务,而是返回将在继续完成时完成的新任务。您正在等待原始任务(如apbTask),您应该等待ContinueWith调用的结果。

于 2013-07-23T13:46:59.497 回答
1

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

这不是错误,而是外部变量捕获与 lambda 一起使用的方式。

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

对 ContinueWith 的调用也是如此。如果您想修改上一步中使用的产品,您应该将其作为结果的一部分传递到下一步,也许使用元组来执行此操作。

于 2013-07-24T08:47:09.537 回答