代码之家  ›  专栏  ›  技术社区  ›  Jeremy Samuel

可能的线程、变量复制问题

  •  1
  • Jeremy Samuel  · 技术社区  · 15 年前

    我们有一个应用程序运行一个类似以下的例程:

    protected string _largeFile;
    
    Execute()   //this executes in basically an infinite loop.
    {
        _largeFile = "";
        DoStuff();
        DoStuff();
        _largeFile = "ReallyBigString"; //sometimes 4-5Mb
          if(_largeFile != "")
          {
           RaiseEvent();
          }
        DoStuff();
        DoSTuff();
        Thread.Sleep(5000);  //wait 5 seconds;
    //repeat
    }
    
    CatchEvent()
    {
         SendLargeFileToWebService(_largeFile);
    }
    

    此代码在我们无法控制的客户机PC上执行。代码基本上会得到一个大文件并将其发送回我们的服务器。问题是,有时返回到Web服务的大文件是空的。我们对此进行了一段时间的研究,并无法确定这是如何发生的。

    唯一似乎有任何优点的解决方案是,引发事件所需的时间太长,以至于当执行方法执行后续时间时,类级别的largefile变量在sendlargefiletowobservice能够执行此操作之前被清除。

    我的问题是:这是否合理?编写代码的开发人员辩称,类级变量的原因是为了避免复制实例变量并将其传递给新线程(可能是事件执行的线程)。这似乎是正确的方法吗?对此,可能没有什么高明的答案,所以如果有人能向我解释一些标准,例如事件论证者与类变量在引发事件时的对比,我会很感激。我也很好奇这个提议的问题是否合理。在评估不同线程的大字符串时,它们是否知道问题。

    2 回复  |  直到 15 年前
        1
  •  4
  •   JaredPar    15 年前

    我对这个情况有点不清楚。但根据您的描述,似乎从多个线程调用了execute方法。如果是这样,那么是的,您肯定有一个bug,因为如果在任何时候运行两个execute方法,那么您将有一个race条件结束。 _largeFile .

    有两种方法可以解决这个问题

    1. 传递的内容 大文件 作为要执行的参数
    2. 在execute方法中添加一个锁,以防止多个线程同时执行它。

    关于他们不想把变量传给懒惰和imho的说法不应该算作一个有效的论据。

        2
  •  1
  •   tony    15 年前

    所以,执行清除大文件,做一些事情,也许重新加载大文件。 如果重新加载,它会通知另一个线程。 然后,另一个线程会花一些时间通过Web或其他方式发送大型文件。 同时,execute可以做一些其他的事情,然后等待5秒钟,然后重复。

    对吗?

    如果是这样,那就是 可能的 在发送发生之前,该大型文件将被清除(返回到执行的顶部)。但是,有一些但是:

    1. 我假设sendLargeFileToWebService(“大文件”); 副本 大文件的值(即复制指针的值,不复制所有内容)? 如果是这样的话,那么您是说在sendLarge之前清除了大型文件…即使 开始 . 考虑到执行会做一些事情,然后等待5秒钟,这看起来很奇怪。但是等等,也许发送大…正忙于发送旧文件,所以当它到达下一个文件时,它错过了它的机会?接球真的是一个循环,对吗?:

      for_ever()
      {
          while (!nothing_to_catch)
              Wait();
          // !oh, caught something
          CatchEvent(); // calls SendLarge... which could take a while
      } // repeat
      

    因此,当catchEvent来检查另一个事件时,“大文件”已经重置。

    还是每个catchEvent()都发生在新线程中?我怀疑。

    1. 我不记得其他的“buts”,因为我认为上面的问题是存在的,即使我不太了解.net等等。

    不管怎样,试试看 -增加你的睡眠时间()(就像一个测试-而不是一个解决方案!) -在大文件周围加锁(再次,作为测试)或传递它

    而且,检查——在大量大文件被“背靠背”发送之后,这种情况会发生吗?这表明我的1方案——即发送线程落后太多,最终落后5秒以上,并丢失文件。理论上,它还可以跳过一个文件,转到下一个文件。发生了吗?

    最后,在我觉得自己 可以 明白你想描述什么-就像另一个答案一样,我发现它不清楚。 所以如果我对这个问题猜错了,那么,嘿,我可能猜错了答案。