программа зависла из-за пропущенных событий - PullRequest
0 голосов
/ 04 сентября 2011

Это тот случай:

В компании есть несколько сайтов, на каждом из которых есть несколько камер, которые ежедневно делают несколько снимков (около тысячи снимков на каждой). Эти изображения затем сохраняются в папке (одна папка на день) на одном компьютере.

Компания владеет программой анализа изображений, которая получает файл "in.xml" в качестве входных данных и возвращает файл "out.xml" для анализа одного изображения. Эта программа должна использоваться и не может быть изменена. Я написал пользовательский интерфейс для этой программы, которая работает в этой папке и обрабатывает каждую камеру с каждого сайта, посылая картинки за картинкой в ​​эту программу, которая работает как отдельный процесс. Поскольку эта обработка асинхронна, я использовал события в начале и в конце обработки каждого изображения, и то же самое для сайтов и камер на сайтах.

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

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

Примеры кода: в классе изображений:

    static public void image_timer_Elapsed(object sender, ElapsedEventArgs e)
    {
        //stop timer and calculate the how much time left for next check for file. 
        _timer.Stop();
        _timerCount += (int)_timer.Interval;
        int timerSpan = (int)(Daily.duration * 1000) - _timerCount; 
                //daily.duration is the max duration for seekin the "out.xml" file before quiting.
        if (timerSpan < _timer.Interval) _timer.Interval = timerSpan + 1;

        //check for file and analize it.
        String fileName = Daily.OutPath + @"\out.xml";
        ResultHandler.ResultOut output = ResultHandler.GetResult(ref _currentImage);

        //if no file found and there is time left wait and check again
        if (output == ResultHandler.ResultOut.FileNotFound && timerSpan > 0)
        {
            _timer.Start();
        }
        else //file found or time left
        {
             if (MyImage.ImageCheckCompleted != null)
                MyImage.ImageCheckCompleted(_currentImage); //throw event
                // the program is probably got stuck here.
        }

По классу камеры:

    static public void Camera_ImageCheckCompleted(MyImage image)
    {
        //if this is not the last image.  (parent as Camera )
        if (image.Id + 1 < image.parent.imageList.Count)
        {
            image.parent.imageList[image.Id + 1].RunCheck(); //check next image
        }
        else
        {
            if (Camera.CameraCheckCompleted != null)
                Camera.CameraCheckCompleted(image.parent); // throw event
        }
    }

1 Ответ

1 голос
/ 04 сентября 2011

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

Итак, прежде всего, я бы предложил броситьtry/catch блокирует весь код, который запускается в отдельном потоке.Если возникнет исключение, вы захотите его перехватить и либо запустите ImageCheckCompleted с некоторыми специальными аргументами события, чтобы указать, что произошла ошибка, либо запустите другое событие, которое вы создали специально для возникновения ошибки.Таким образом, ваша программа может продолжать обрабатывать, даже если в вашем коде возникнет исключение.

try
{
    //... Do your processing

    // This will happen if everything worked correctly.
    InvokeImageCheckCompleted(new ImageCheckCompletedEventArgs();
}
catch (Exception e)
{
    // This will happen if an exception got thrown.
    InvokeImageCheckCompleted(new ImageCheckCompletedEventArgs(e);
}

Для простоты я бы предложил использовать цикл for для обработки каждого изображения.Вы можете использовать ManualResetEvent для блокировки выполнения до тех пор, пока не сработает событие ImageCheckCompleted для каждой проверки.Это должно упростить ведение журнала выполнения каждого цикла, выявить ошибки, которые могут препятствовать запуску события ImageCheckCompleted, и даже, возможно, перейти к обработке следующего изображения, если один из них, кажется, занимает слишком много времени.

Наконец, если вы можете сделать обработку изображений поточно-ориентированной, вы можете рассмотреть возможность использования Parallel.ForEach, чтобы сделать так, чтобы несколько изображений могли обрабатываться одновременно.Это, вероятно, значительно улучшит общую скорость обработки пакета.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...