Небольшая помощь требовала перехвата событий, возникающих в отдельном потоке - PullRequest
0 голосов
/ 29 ноября 2010

Для начала я работаю над файловой системой довольно высокого уровня, где мне нужно иметь возможность (с очень высокой точностью) своевременно идентифицировать и обрабатывать файлы.С учетом сказанного, я работаю в системе, которая будет использовать FileSystemWatcher.Однако вся проблема с наблюдателем заключается в том, что у него, как правило, возникают проблемы при создании событий, когда задействованы большие файлы.

Чтобы исправить это, я работаю над абстрактным классом, который может обрабатывать файлы индивидуально один раз.они создаются наблюдателем файловой системы.

Текущий дорожный блок, с которым я сталкиваюсь, заключается в том, что моя внепроцессная проверка файла вызывает событие, у меня просто возникают проблемы с его перехватом.

public abstract class absFile
    {
        public delegate void FileAvailable(object sender, FileEventArgs e);
        public event FileAvailable OnFileAvailable;

        public void isAvailable()
        {
            // Create a new threaded instance of the AvailableCheck private void
            // This method will be run out of process to allow other operations to continue.
            Thread toAvailableCheck = new Thread(new ThreadStart(AvailableCheck));

            // Once the threaded object is created, start it.
            toAvailableCheck.Start();
        }

 private void AvailableCheck()
        {
            // Declaring the file stream toThisFile to be used later with the File.Open
            FileStream toThisFile;

            // Declaring and instantiating the attempt counter for the loop
            int tiAttemptNumber = 0;

            // Declaring the event args for returning the events that are
            // used by this object.

            FileEventArgs toFileEventArgs = new FileEventArgs();

            do {
                try
                {
                    // Attempt to open the file.  If this fails the try
                    // will interrupt the processing and it will be caught.
                    toThisFile = File.Open(this.FilePath, FileMode.Open);

                    // If the file.open method does not fail, the isFileAvailable
                    // property will be set to true by updating the mbIsAvailable
                    // private boolean.
                    mbIsAvailable = true;

                    // populate the file event args to send back 
                    // the number of attempts made at the file and the pause lenght
                    toFileEventArgs.Attempts = tiAttemptNumber;
                    toFileEventArgs.Pause = this.AttemptPause / 1000;

                    // This event is called when the file is complete.
                    // The client application will be able to handle this event.
                    OnFileAvailable(this, toFileEventArgs);


                    // close and dispose of the filestream.
                    toThisFile.Close();
                    toThisFile.Dispose();
                }
                catch (Exception toException)
                {
                    // Since the open failed, add 1 to the counter so that
                    // it will eventually time out.
                    tiAttemptNumber++;

                    // Set the isFileAvailable property to false.  This property
                    // will default as false, but as a part of standard, make sure that
                    // if the open fails that the flag IS set to false by updating the 
                    // mbIsAvailable private boolean.
                    mbIsAvailable = false;

                    // Put the thread to sleep for the ammount of time specified
                    // by the AttemptPause.  This will give the file time to finish
                    // whatever process it is involved in.
                    Thread.Sleep(this.AttemptPause);
                }

              // Continue to make attempts until either the file is marked as available
              // or the number of current attempts is the same as or greater than the
              // AccessAttempts property.
            } while (!this.isFileAvailable && this.AccessAttempts > tiAttemptNumber);
        }

это код, который я запускаю, как вы можете видеть в закрытом void AvailableCheck, OnfileAvailable - это делегат, вызывающий его, и аргументы события файла.

теперь я унаследовал этоабстрактный класс, и мне нужно иметь возможность перехватить это событие.

        toWatcher.Created += new FileSystemEventHandler(OnCreated);

вызывается в основном и далее по коду - следующий метод

private void OnCreated(object source, FileSystemEventArgs e)
{
    lstStatus.Invoke(new MethodInvoker(delegate { 
        lstStatus.Items.Add(DateTime.Now.ToString("g") + " - " + e.Name + " - File Created Event Detected for: " + e.FullPath);
        lstStatus.TopIndex = lstStatus.Items.Count - 1;
        tgtFile ThisFile = new tgtFile(e.FullPath);
        lstStatus.Items.Add(DateTime.Now.ToString("g") + " - " + e.Name + " - Creating tgtFile Object");
    }));
}

СозданиеОбъекту tgtFile передается путь, который проходит через щуку к доступному методу.

, как вы можете видетьсуществует вероятность того, что событие OnFileAvailable будет запущено из объекта tgtFile.

Также, как вы можете видеть, существует возможность одновременного существования нескольких объектов tgtFile в памяти, что также основано на дизайне потоковфайловой системыwatcher.

в моем основном приложении, тогда я хочу иметь возможность сделать что-то вроде:

public tgtFile ThisFile;
ThisFile.OnFileAvailable += new EventHandler(OnFileAvailable);

, но EventHandler выдает ошибки, и вот где я застрял.

Ответы [ 2 ]

2 голосов
/ 30 ноября 2010

Если он выдает ошибку компилятора, возможно, это потому, что ваш метод "OnFileAvailable", на который есть ссылка в этой строке (в нижней части вашего поста):

ThisFile.OnFileAvailable += new EventHandler(OnFileAvailable);

не ожидает EventHandler -он ожидает делегата FileAvailable.Измените его на:

ThisFile.OnFileAvailable += new absFile.FileAvailable(OnFileAvailable);
//note that this can also just be ThisFile.OnFileAvailable += OnFileAvailable;

и убедитесь, что OnFileAvailable выглядит следующим образом:

public void OnFileAvailable(object sender, FileEventArgs e)
{
   //...
}
0 голосов
/ 30 ноября 2010

Перво-наперво ... Убедитесь, что событие подписано, прежде чем вызывать его. Оберните вызов события в оператор IF:

if (OnFileAvailable != null)
    OnFileAvailable(this, toFileEventArgs); 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...