2013-06-20 31 views
0

我有这个程序创建线程,我必须创建队列文件夹和 检查文件。由C#程序线程创建的目录被锁定

现在我注意到在处理大量文件后我的程序没有问题。 我产生了一个UnauthorizedAccessException,所以我去找那个文件夹,它似乎 该文件夹已完全锁定?!

这是我的防病毒阻止访问还是我必须修复我的线程?

Queue

public class worker 
{ 

    public bool Stopping = false; 

    private System.Timers.Timer _timer; 
    private List<string> _files; 

    #region Feedback 

    public event FeedbackHandler Feedback; 
    public delegate void FeedbackHandler(object sender, string text); 

    #endregion 

    #region Properties 

    private string _name; 
    public string Name 
    { 
     get { return _name; } 
    } 

    private string _folder; 
    public string Folder 
    { 
     get { return _folder; } 
     set { _folder = value; } 
    } 

    private string _outfolder = Path.Combine(shared.Root, "out"); 
    public string Outfolder 
    { 
     get { return _outfolder; } 
     set { _outfolder = value; } 
    } 

    private string _backupfolder = Path.Combine(shared.Root, "backup"); 
    public string Backupfolder 
    { 
     get { return _backupfolder; } 
     set { _backupfolder = value; } 
    } 

    private string _filter = "*.*"; 
    public string Filter 
    { 
     get { return _filter; } 
     set { _filter = value; } 
    } 

    private SearchOption _subfolders = SearchOption.TopDirectoryOnly; 
    public bool Subfolders 
    { 
     get { return (_subfolders == SearchOption.AllDirectories); } 
     set { if (value) { _subfolders = SearchOption.AllDirectories; } else { _subfolders = SearchOption.TopDirectoryOnly; } } 
    } 

    #endregion 

    #region Constructor 

    public worker(string Name) 
    { 
     _name = Name; 

     _folder = Path.Combine(shared.Root, "queues"); 
     _folder = Path.Combine(_folder, Name); 

    } 

    #endregion 

    #region Destructor 

    ~worker() 
    { 

    } 

    #endregion 

    #region Control 

    public void Start() 
    { 

     Stopping = false; 

     Directory.CreateDirectory(_folder); 

     _timer = new System.Timers.Timer(1); 
     _timer.Elapsed += new ElapsedEventHandler(_timer_Elapsed); 
     _timer.Start(); 

     Feedback(this, "[" + _name + "] started!"); 

    } 

    public void Stop() 
    { 

     Stopping = true; 

     Feedback(this, "[" + _name + "] stopped..."); 

    } 

    void _timer_Elapsed(object sender, ElapsedEventArgs e) 
    { 

     if (Stopping) 
     { 
      _timer.Stop(); 
      _files.Clear(); 

      return; 
     } 

     _timer.Stop(); 

     Process(); 

     _timer.Start(); 
    } 

    #endregion 

    void Process() 
    { 

     if (Directory.Exists(_folder)) 
     { 

      _files = Directory.GetFiles(_folder, _filter, _subfolders).ToList(); 

      foreach (string _file in _files.ToArray()) 
      { 

       if (Stopping) { break; } 

       document _document = new document(_file); 

       _document.Copy(_backupfolder); 
       _document.Move(_outfolder); 

      } 

      _files = new List<string>(); 

     } 

    } 

} 



public class document 
{ 

    private string _header; 

    #region Feedback 

    public event FeedbackHandler Feedback; 
    public delegate void FeedbackHandler(object sender, string text); 

    #endregion 

    #region Properties 

    private string _file; 
    public string File 
    { 
     get { return _file; } 
    } 

    private job _job; 
    public job Job 
    { 
     get { return _job; } 
    } 

    #endregion 

    #region Constructor 

    public document(string File) 
    { 
     _file = File; 

     _header = shared.FileOperations.ReadHeader(_file); 

     _job = new job(_file, _header); 
     _job.ReadHeader(); 

    } 

    #endregion Constructor 

    public void Copy(string Folder) 
    { 
     string _backupfile; 

     _backupfile = Path.Combine(Folder,_job.Name); 
     _backupfile = Path.Combine(_backupfile,_job.Company); 
     _backupfile = Path.Combine(_backupfile, DateTime.Now.ToString("yyyy")); 
     _backupfile = Path.Combine(_backupfile, DateTime.Now.ToString("MMMM")); 

     Directory.CreateDirectory(_backupfile); 

     _backupfile = Path.Combine(_backupfile, Path.GetFileName(_file)); 

     shared.FileOperations.CopyFile(_file, _backupfile, true); 

    } 

    public void Move(string Folder) 
    { 

     string _outfile; 

     _outfile = Path.Combine(Folder, Path.GetFileNameWithoutExtension(_file)); 

     shared.FileOperations.MoveFile(_file, _outfile, true); 
    } 
} 



public struct shared 
{ 
    public static string Root 
    { 
     get 
     { 
      string _base = System.AppDomain.CurrentDomain.BaseDirectory.ToString(); 
      return Directory.GetParent(_base).Parent.FullName.ToString(); 
     } 
    } 

    public struct Patterns 
    { 
     public const string Header = @"\^?JOB\s(?<JOB>[a-zA-Z0-9]+[0-9]{3})[D]?(?<ACTION>[JFE]+)(?<COMPANY>[A-Z]{2,2})\s" + 
             @"(?<EMAIL>-emto=.*)?" + 
             @"-C(?<COPIES>[0-9]{2,2})\s" + 
             @"-Z""(?<PRINTER>[A-Z0-9]+)""\s" + 
             @"(?:\^?PAGE 01|(?<FAX>\^?FAX.*)\s\^?PAGE 01?)"; 

     public const string Jump = @"\^PAGE\s[0-9]+"; 

     public const string Pages = @"(\$?PAGE\s)"; 

     public const string Fax = @"\^?FAX FROM_COMPANY\s""(?<FROM>.*)""\s" + 
              @"\^?FAX FROM_FAX_NUM\s""(?<FFAX>.*)""\s" + 
              @"\^?FAX FROM_NAME\s""(?<FNAME>.*)""\s" + 
              @"\^?FAX TO_FAX_NUM\s""(?<TFAX>.*)""\s" + 
              @"\^?FAX TO_COMPANY\s""(?<TO>.*)""\s" + 
              @"\^?FAX TO_NAME\s""(?<TNAME>.*)""\s" + 
              @"\^?FAX WHO\s""(?<WHO>.*)""\s" + 
              @"\^?FAX ID\s+(?<ID>.*)"; 

     public const string Mail = @"-em([^\s=]+)=(""[^""]*""|[^\s]+)"; 

     public const string Seperator = @"^"; 

    } 

    public struct FileOperations 
    { 

     // Encoding 
     public static Encoding ReadEncoding = Encoding.GetEncoding(1252); 
     public static Encoding WriteEncoding = Encoding.UTF8; 

     // Timeouts 
     static int Timeout = 1; 
     static int FileTimeout = 10000; // 10 seconds/file permitted.. 

     // Header 
     public static string ReadHeader(string SourceFile) 
     { 
      return ReadHeader(SourceFile, Patterns.Jump); 
     } 

     public static string ReadHeader(string SourceFile, string Beacon) 
     { 

      WaitFile(SourceFile); 

      string r = null; 
      string l = null; 

      try 
      { 
       StreamReader _reader = new StreamReader(SourceFile, ReadEncoding); 
       Match _match; 

       do 
       { 

        l = _reader.ReadLine(); 
        r += l + " "; 

        _match = Regex.Match(l, Beacon); 

       } while (!_match.Success); 

       _reader.Close(); 

      } 
      catch (Exception ex) 
      { 

       // todo 
       if (Debugger.IsAttached) { throw ex; } 

      } 

      return r; 

     } 

     // Read Contents 
     public static List<string> ReadFile(string SourceFile) 
     { 
      return ReadFile(SourceFile, Patterns.Seperator); 
     } 
     public static List<string> ReadFile(string SourceFile, string Seperator) 
     { 

      WaitFile(SourceFile); 

      List<string> lines = new List<string>(); 

      try 
      { 

       StreamReader sr = new StreamReader(SourceFile, Encoding.GetEncoding(1250)); 
       string tmp = null; 
       string line = null; 

       while (!sr.EndOfStream) 
       { 

        line = sr.ReadLine(); 

        if (!string.IsNullOrEmpty(line) && line.Substring(0, 1) == Seperator) 
        { 
         if (!string.IsNullOrEmpty(tmp)) 
         { 
          lines.Add(tmp); 
         } 

         tmp = line.Replace(Seperator, "^"); 

        } 
        else 
        { 

         tmp += Environment.NewLine + line; 

        } 

       } 

       sr.Close(); 

       if (!string.IsNullOrEmpty(tmp)) 
       { 
        lines.Add(tmp); 
       } 

      } 
      catch (Exception ex) 
      { 
       // todo 
       if (Debugger.IsAttached) {throw ex;} 

      } 

      return lines; 

     } 

     // Write Contents 
     public static void WriteFile(string DestinationFile, List<string> Lines) 
     { 
      try 
      { 
       File.WriteAllLines(DestinationFile, Lines.ToArray(), WriteEncoding); 
      } 
      catch (Exception ex) 
      { 
       // todo 
       if (Debugger.IsAttached) { throw ex; } 
      } 

     } 

     public static void WriteFile(string DestinationFile, string Contents) 
     { 
      try 
      { 
       File.WriteAllText(DestinationFile, Contents); 
      } 
      catch (Exception ex) 
      { 
       // todo 
       if (Debugger.IsAttached) { throw ex; } 
      } 
     } 

     // Move File 
     public static void MoveFile(string SourceFile, string DestinationFile, bool Overwrite) 
     { 
      WaitFile(SourceFile); 

      try 
      { 
       string _count = null; 
       string _destination = Path.GetDirectoryName(DestinationFile); 
       string _file = Path.GetFileNameWithoutExtension(DestinationFile); 
       string _extension = Path.GetExtension(DestinationFile); 

       string[] _files = Directory.GetFiles(_destination, _file + "*"); 

       if (_files.Length > 0) 
       { 
        if (Overwrite) 
        { 
         for (int x = 0; x <= _files.Length - 1; x++) 
         { 
          File.Delete(_files[x]); 
         } 
        } 
        else 
        { 
         _count = "_" + (_files.Length - 1).ToString("D4"); 
        } 

       } 

       DestinationFile = Path.Combine(_destination, _file + _count + _extension); 

       File.Move(SourceFile, DestinationFile); 

      } 
      catch (Exception ex) 
      { 
       if (Debugger.IsAttached) { throw ex; } 
      } 

     } 

     public static void CopyFile(string SourceFile, string DestinationFile, bool Overwrite) 
     { 
      WaitFile(SourceFile); 

      try 
      { 
       string _count = null; 
       string _destination = Path.GetDirectoryName(DestinationFile); 
       string _file = Path.GetFileNameWithoutExtension(DestinationFile); 
       string _extension = Path.GetExtension(DestinationFile); 

       string[] _files = Directory.GetFiles(_destination, _file + "*"); 

       if (_files.Length > 0) 
       { 
        if (Overwrite) 
        { 
         for (int x = 0; x <= _files.Length - 1; x++) 
         { 
          File.Delete(_files[x]); 
         } 
        } 
        else 
        { 
         _count = "_" + (_files.Length - 1).ToString("D4"); 
        } 

       } 

       DestinationFile = Path.Combine(_destination, _file + _count + _extension); 

       File.Copy(SourceFile, DestinationFile); 

      } 
      catch (Exception ex) 
      { 
       if (Debugger.IsAttached) { throw ex; } 
      } 
     } 

     // Delete File 
     public static void DeleteFile(string SourceFile) 
     { 
      WaitFile(SourceFile); 

      try 
      { 
       File.Delete(SourceFile); 
      } 
      catch (Exception ex) 
      { 
       // todo 
       if (Debugger.IsAttached) { throw ex; } 
      } 

     } 

     // Check File 
     static void WaitFile(string SourceFile) 
     { 
      Timeout = 1; 

      while (!File.Exists(SourceFile)) 
      { 
       System.Threading.Thread.Sleep(Timeout); 

       Timeout++; 

       if (Timeout == FileTimeout) 
       { 
        // todo 
        if (Debugger.IsAttached) { throw new Exception("Timout exceeded!"); } 
       } 
      } 

      Timeout = 1; 

      while (!IsFileReady(SourceFile)) 
      { 
       System.Threading.Thread.Sleep(Timeout); 

       Timeout++; 

       if (Timeout == FileTimeout) 
       { 
        // todo 
        if (Debugger.IsAttached) { throw new Exception("Timout exceeded!"); } 
       } 

      } 
     } 
     static bool IsFileReady(String SourceFile) 
     { 
      try 
      { 
       using (FileStream inputStream = File.Open(SourceFile, FileMode.Open, FileAccess.Read, FileShare.None)) 
       { 
        if (inputStream.Length > 0) 
        { 
         return true; 
        } 
        else 
        { 
         return false; 
        } 

       } 
      } 
      catch (Exception) 
      { 
       return false; 
      } 
     } 

    } 

    public struct Functions 
    { 

     public static string CleanXML(string Text) 
     { 

      Text = Text.Replace(@"&", @"&amp;"); 
      Text = Text.Replace(@"<", @"&lt;"); 
      Text = Text.Replace(@">", @"&gt;"); 
      Text = Text.Replace(@"""", @"&quot;"); 
      Text = Text.Replace(@"'", @"&apos;"); 

      return Text; 
     } 
    } 
} 



void Work(string Name) 
    { 
     _worker = _workers.FirstOrDefault(w => w.Name == Name); 

     if (_worker == null) 
     { 

      _worker = new worker(Name); 
      _worker.Feedback+=new worker.FeedbackHandler(Feedback); 

      _worker.Folder = Path.Combine(_queuefolder, Name); 
      _worker.Outfolder = _outfolder; 
      _worker.Backupfolder = _backupfolder; 

      _workers.Add(_worker); 

      Thread _thread = new Thread(_worker.Start); 

      _thread.Start(); 
      _thread.Join(); 
     } 
    } 
+10

你应该发布你的**代码** ...你在你的线程中做了什么?如果你只是创建文件夹,那么没有任何东西被锁定,但如果你打开一个文件(或者你创建一个FileSystemWatcher),那么它们将被锁定,直到你处理该资源。 –

+1

您能否提供与创建文件夹/文件相关的代码?我的第一个猜测是它与你的线程有关。 – Abbas

+0

用代码更新的问题... – grmbl

回答

1

为了澄清我的意思:

//worker class 
private volatile bool _stopping; 
private Thread _thread; 

public void Start() 
{ 

    _stopping = false; 

    Directory.CreateDirectory(_folder); 

    _thread = new Thread(Process); 
    _thread.Start(); 

    Feedback(this, "[" + _name + "] started!"); 

} 

public void Stop() 
{ 

    _stopping = true; 
    _thread.Join(); 

    Feedback(this, "[" + _name + "] stopped..."); 

} 

private void Process() 
{ 
    while(!_stopping) 
    { 
     ...... 
     Thread.Sleep(100); 
    } 
} 

因为使用计时器的方式......这是错误的。尽管有趣的是,为什么Windows会锁定文件夹,您应该从做一些重构开始。它可能实际上解决您的问题。

+0

非常感谢Nik,我会回顾一下我的代码,看看我能否使它更高效,更不容易出错......我为什么要使用定时器? 我试过使用Filesystemwatcher,但我无法以正确的方式在 中实现它。 (查看其他人对此对象有问题) – grmbl