C# 并发读写文件

C# 并发读写文件,c#,concurrency,C#,Concurrency,目前,我正在编写windows服务来处理大量xml文件,并将xml文件中的信息保存到数据库中。有3台计算机运行指向同一共享位置的相同服务。我总是遇到一个异常,在这个过程中找不到文件,不知道如何解决这个问题。我试图从目录中获取所有文件,并根据机器名重命名这些文件,并允许每台机器处理它自己的一组文件,但仍然遇到“找不到文件”异常。谁能告诉我处理这件事的正确方法吗 多谢各位 代码 if(目录存在(文件夹)) { 字符串模式=“.xml”; 字符串machineName=System.Environme

目前,我正在编写windows服务来处理大量xml文件,并将xml文件中的信息保存到数据库中。有3台计算机运行指向同一共享位置的相同服务。我总是遇到一个异常,在这个过程中找不到文件,不知道如何解决这个问题。我试图从目录中获取所有文件,并根据机器名重命名这些文件,并允许每台机器处理它自己的一组文件,但仍然遇到“找不到文件”异常。谁能告诉我处理这件事的正确方法吗

多谢各位

代码

if(目录存在(文件夹))
{
字符串模式=“.xml”;
字符串machineName=System.Environment.machineName;
string[]files=Directory.GetFiles(文件夹、模式、SearchOption.AllDirectories);
newExt=string.Format(“{0}.{1}”,machineName,newExt);
for(int i=0;i!string.IsNullOrEmpty(f)和&f.Contains(machineName))
.订购人(f=>f,分拣机);
}

如果不查看您的代码,很难看到发生了什么,但我推测这三台服务器会获得一个目录列表,从该列表中选择一个文件进行处理,同时另一台服务器已重命名该文件,因为另一台服务器决定开始处理该文件

如果这种情况很少发生,您可以忽略异常(假设我的解释是正确的)。如果这种情况经常发生,你需要更详细地解释你在做什么


您可以通过让每台服务器以不同的方式(例如,一个a-Z、第二个Z-a、第三个L-Z、a-J等)对文件列表进行排序,然后按照排序顺序选择最上面的一个文件来减少对同一文件的争用。

请您解释一下目录中出现的文件的名称好吗

  • 如果文件的名称中已经有目标machinename,那么每台计算机只处理这些命名文件就足够了(或者不处理??)
  • 如果出现的文件没有指定任何特殊的machinename,那么看起来就像是工作服务之间的竞争,谁先捕获一个文件。然后,您的异常似乎是可以预期的(正如Eric J.所说),您只需尝试..捕获它并忽略该文件。它是Normal,其他一些服务已经捕获了该文件。或者您可以考虑一些资源共享技术,以避免多个服务同时检查目录。至少您可以创建一些子目录,将所有文件分成若干组,并使每个服务与每个子目录一起工作

  • 旁白:当然,如果你觉得我没有抓住这个问题,请你提供一些更准确的信息。

    正如Eric J提到的,你可以忽略错误:

    if (Directory.Exists(folder))
    {
      string pattern = ".xml";
      string machineName = System.Environment.MachineName;
      string[] files = Directory.GetFiles(folder, pattern, SearchOption.AllDirectories);  
      newExt = string.Format("{0}.{1}", machineName, newExt);
    
      for (int i = 0; i < files.Length; i++)
      {
          try
          {
              if (files[i].Contains(machineName))
              {
                   //replace this new extension
                   files[i].Replace(machineName + ".", "");
              }
              else
              {
                   files[i] = ChangeExtension(files[i], newExt, true);
              }
         catch(FileNotFoundException ex)
         {   
         } 
      }
    
      IEnumerable<string> sortedFiles = files.Where(f => !string.IsNullOrEmpty(f) && f.Contains(machineName))
                                             .OrderBy(f => f, Sorter);
    }
    
    if(目录存在(文件夹))
    {
    字符串模式=“.xml”;
    字符串machineName=System.Environment.machineName;
    string[]files=Directory.GetFiles(文件夹、模式、SearchOption.AllDirectories);
    newExt=string.Format(“{0}.{1}”,machineName,newExt);
    for(int i=0;i!string.IsNullOrEmpty(f)和&f.Contains(machineName))
    .订购人(f=>f,分拣机);
    }
    
    为了排除明显的问题……如果服务仅在一台机器上运行,您是否会收到“未找到文件”异常?如果服务在一台机器上运行,则系统工作正常。此问题是由于两台机器捕获文件的同一快照并在同一时间处理。我在上面添加的代码非常简单。ChangeExtension重命名文件以附加机器名很简单正如@eric所述,您应该忽略异常并继续工作。我猜您重命名文件以将其标记为“正在扫描”,因此让一台机器捕获它,而其他机器跳过它的逻辑很好。至少对我来说是这样。
    if (Directory.Exists(folder))
    {
      string pattern = ".xml";
      string machineName = System.Environment.MachineName;
      string[] files = Directory.GetFiles(folder, pattern, SearchOption.AllDirectories);  
      newExt = string.Format("{0}.{1}", machineName, newExt);
    
      for (int i = 0; i < files.Length; i++)
      {
          try
          {
              if (files[i].Contains(machineName))
              {
                   //replace this new extension
                   files[i].Replace(machineName + ".", "");
              }
              else
              {
                   files[i] = ChangeExtension(files[i], newExt, true);
              }
         catch(FileNotFoundException ex)
         {   
         } 
      }
    
      IEnumerable<string> sortedFiles = files.Where(f => !string.IsNullOrEmpty(f) && f.Contains(machineName))
                                             .OrderBy(f => f, Sorter);
    }