【问题标题】:Only last task runs!只有最后一个任务运行!
【发布时间】:2011-07-12 01:54:50
【问题描述】:

我迫切希望找到解决问题的方法。

以下是为List<AccountContactView>中的每个项目生成不同任务的代码。

List<AccountContactViewModel> selectedDataList
    = DataList.Where(
        dataList => (bool) dataList.GetType()
                                   .GetProperty("IsChecked")
                                   .GetValue(dataList, new object[0]) == true
      ).ToList();

this.IsEnabled = false;

Task validateMarked = Task.Factory.StartNew(() =>
{
    foreach (AccountContactViewModel viewModel in selectedDataList)
    {
        if (viewModel != null)
        {
            Task validate = Task.Factory.StartNew(
                () => ValidateAccount(viewModel),
                (TaskCreationOptions)TaskContinuationOptions.AttachedToParent);
        }
    }
});

validateMarked.ContinueWith(x => this.IsEnabled = true);

现在我的问题是当它运行时,它只针对数组中的最后一项运行。知道我做错了什么吗?

我不想使用Parallel.ForEach,因为它没有提供必要的并行效果来根据每个任务的完成来增加进度条。

【问题讨论】:

  • 几乎每天都有人在 SO 上问这个问题。您正在关闭循环内的循环变量。详情请见blogs.msdn.com/b/ericlippert/archive/2009/11/12/…
  • 次要问题,但如果您要做的只是在foreach 中枚举它,则无需在您的DataList 查询中调用.ToList()

标签: c# .net wpf task-parallel-library


【解决方案1】:

这可能是 lambda 范围问题。

在将 viewModel 传递给 StartNew 方法之前,您是否尝试将其分配给局部变量

...
Task validateMarked = Task.Factory.StartNew(() =>
{
    foreach (AccountContactViewModel viewModel in selectedDataList)
    {
        var localViewModel = viewModel;
        if (localViewModel != null)
        {
            Task validate = Task.Factory.StartNew(
                () => ValidateAccount(localViewModel),
                (TaskCreationOptions)TaskContinuationOptions.AttachedToParent);
        }
    }
});
...

【讨论】:

  • 老兄,为什么必须将 viewModel 分配给局部变量。我已经看到 Resharper 抱怨这个太多次了。顺便说一下 +1。
  • 查看来自 cmets 的 Eric Lippert 文章到原始问题。他解释得很好。谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-06-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-12
  • 1970-01-01
相关资源
最近更新 更多