0

我有这个程序创建线程,我必须在其上创建队列文件夹并检查它们的文件。

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

这可能是我的防病毒阻止访问还是我必须在我的线程上修复的东西?

队列

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();
        }
    }
4

1 回答 1

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 会锁定文件夹,但您应该从进行一些重构开始。它实际上可能会一路解决您的问题。

于 2013-06-20T11:23:49.290 回答