0

似乎如果给定线程由于任何原因失败,这将导致无限循环。

这是不是我写的代码,所以我什至无法编辑它,但我认为这里最明显的问题是计数器变量totalActions没有标记为易失性,因此线程没有看到最多最新的价值。

所以看起来如果它永远不会得到 的真正价值totalActions,它会一直等待吗?

这会导致线程递归运行吗?在调试时,我注意到执行线程失败(抛出异常),并且它只是不断地被一遍又一遍地调用......

public void PerformActions(List<Action> actions)
{
   object actionLock = new object();
   int totalActions = actionts.Count;

   for(int x = 0; x < accounts.Count; x++)
   {
      int y = x;
      new Thread(delegate()
      {
        actions[y].Invoke();

        if(Interlocked.Decrement(ref totalActions) == 0)
        {
            lock(actionLock)
            {
                Monitor.Pulse(actionLock);
            }
        }
    }).Start();
   }

   lock(actionLock)
   {
        if(totalActions > 0)
        {
           Monitor.Wait(actionLock);
        }    
   }
}

更新

myService用法是这样的,其中httpRequest调用从 API 服务获取 json 请求。

Execute.InParallel(
new Action[]
    {
    () => { abc = myService.DoSomething(); },
    () => { def = myService.DoSomethingElse(); }
    });
4

2 回答 2

0

锁将充当内存屏障,确保您的测试if(totalActions > 0)读取当前值。我不相信这段代码是无种族的,但种族至少是非常非常不可能的。你很难复制它。

所以问题是这里没有显示的其他东西。你能用调试器找出所涉及的线程到底在做什么吗?

您说某些线程由于未处理的异常而死亡。也许线程提前退出会导致计数不减少。

另外,如果您无法更改代码,那么问题的重点是什么?我不知道该给你什么建议。

于 2013-05-01T19:55:46.633 回答
0

循环不正确 - 因为变量 x 被错误地捕获。actions[x].Invoke();在每个线程中执行时,它将始终具有 x 的最后一个值。因此,传递给数组的最后一个委托将被多次调用。

正确的做法是这样的

    for(int x = 0; x < accounts.Count; x++)
       {
          int y = x; // here correct value of y will be captured in delegate
          new Thread(delegate()
          {
            actions[y].Invoke();
   ...
于 2013-05-01T20:45:48.720 回答