【问题标题】:Passing value parameter to Task in c#在c#中将值参数传递给Task
【发布时间】:2014-05-22 17:29:42
【问题描述】:

我在将 long by value 传递给 Task 时遇到问题。

我有一个 ID 列表,在其中循环遍历每个 ID,分配给局部变量,然后作为参数传递给新任务。在循环并处理下一个 ID 之前,我不会等待任务完成。我保留了一系列任务,但这无关紧要。

loop
    long ID = list[index];
    task[index] = Task.Factory.StartNew(() => doWork(ID));
end loop

如果列表包含例如 100 和 200。我希望使用 100 调用第一个任务 然后用 200 调用第二个任务。但它没有,doWork 为这两个任务收到 200,因此在复制值时会出现问题。

我可以用一些简单的控制台代码来演示

class Program
{
   static void Main(string[] args)
   {
      long num = 100;
      Task one = Task.Factory.StartNew(() => doWork(num));
      num = 200;

      Console.ReadKey();
   }

   public static void doWork(long val)
   {
      Console.WriteLine("Method called with {0}", val);
   }
 }

上面的代码会一直显示

使用 200 调用的方法

我修改了代码等待任务状态从WaitingToRun切换

static void Main(string[] args)
{
   long num = 100;
   Task one = Task.Factory.StartNew(() => doWork(num));
   while(one.Status == TaskStatus.WaitingToRun)
   {}
   num = 200;

   Console.ReadKey();
}

这改善了事情,但不是 100% 证明,经过几次运行后,我得到了 200 调用的方法

还尝试了以下

while (true)
{
    if (one.Status == TaskStatus.Running | one.IsCompleted == true)
    break;
}

但又显示了 200 个。

您有什么想法可以保证在不等待任务完成的情况下传递给任务的值?

任何帮助/建议表示赞赏 阿德

【问题讨论】:

    标签: c# task


    【解决方案1】:

    您有什么想法可以保证在不等待任务完成的情况下传递给任务的值?

    当然 - 只需创建一个单独的变量,没有在其他任何地方修改。您可以使用新的范围来明确这一点:

    long num = 100;
    Task one;
    {
        // Nothing can change copyOfNum!
        long copyOfNum = num;
        one = Task.Factory.StartNew(() => doWork(copyOfNum));
    }
    

    您不能更改 C# 编译器来捕获“创建委托时变量的值”而不是捕获变量,但您可以确保变量在之后不会更改,这完成了同样的事情。

    【讨论】:

    • 让我开心... :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-02-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-01
    • 1970-01-01
    相关资源
    最近更新 更多