Служба Windows на основе C # - пытается выполнить отладку JIT в производственной среде - PullRequest
3 голосов
/ 20 октября 2010

Я получаю эту ошибку в журналах событий для службы, запущенной в производство:

Произошло необработанное исключение win32 в RivWorks.FeedHandler.exe [5496]. Just-In-Time отладка этого исключения не удалось из-за следующей ошибки: Не удалось запустить отладчик, потому что ни один пользователь не вошел в систему.

У меня установлено и работает под глобальной учетной записью Win NT. Я понятия не имею, почему он пытается перейти в режим отладки. Он был построен по модели выпуска. Работает на 4.0 Framework.

Когда я запускаю на своем компьютере разработчика через точку входа EXE вместо точки входа WinSvc, все работает просто отлично, НО - я уже в режиме «отладки».

Есть идеи, что искать?


2010-10-21 - ПРИМЕЧАНИЕ. - Изменена база кода.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.IO;
using sysIO = System.IO;
using RivWorks.FeedHandler;
using System.Collections;

namespace RivWorks.FeedHandler.Service
{
    public partial class FeedListener : ServiceBase
    {
        #region Declarations
        private List<string> _keys = new List<string>();
        private System.Threading.Timer _clock = null;
        private FileSystemWatcher _watcher;
        private BackgroundWorker _worker;
        private Queue<string> _queue = new Queue<string>();
        private bool _isDequeueing = false;
        #endregion

        #region Constructor
        public FeedListener()
        {
            InitializeComponent();
        }
        #endregion

        #region Start/Stop
        protected override void OnStart(string[] args)
        {
            try
            {
                WriteToEventLog("Enter Start", EventLogEntryType.Information);
                _keys.AddRange(new string[] { "csv", "xml", "zip", "rivx" });

                _worker = new BackgroundWorker();
                _worker.WorkerReportsProgress = true;
                _worker.WorkerSupportsCancellation = true;
                _worker.DoWork += new DoWorkEventHandler(BackgroundWorkerDoWork);
                _worker.ProgressChanged += new ProgressChangedEventHandler(BackgroundWorkerProgressChanged);
                _worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(BackgroundWorkerRunWorkerCompleted);

                _watcher = new FileSystemWatcher(AppSettings.Default.FTPRootPath, "*.*");
                _watcher.IncludeSubdirectories = true;
                _watcher.NotifyFilter = sysIO.NotifyFilters.DirectoryName | sysIO.NotifyFilters.FileName | sysIO.NotifyFilters.LastAccess | sysIO.NotifyFilters.CreationTime | sysIO.NotifyFilters.LastWrite;
                _watcher.Created += new sysIO.FileSystemEventHandler(fileCreatedOrChanged);
                _watcher.Changed += new sysIO.FileSystemEventHandler(fileCreatedOrChanged);
                _watcher.EnableRaisingEvents = true;

                // check every 15 minutes...
                _clock = new System.Threading.Timer(Tick, null, 0, 900000);
                WriteToEventLog("Exit Start", EventLogEntryType.Information);
            }
            catch (Exception ex)
            {
                WriteToEventLog(ex, EventLogEntryType.Error);
                this.Stop();
            }
        }
        protected override void OnStop()  
        {
            try
            {
                _watcher.Dispose();
                _watcher = null;
                _clock.Dispose();
                _clock = null;
                _worker.Dispose();
                _worker = null;
            }
            catch (Exception ex)
            {
                WriteToEventLog(ex, EventLogEntryType.Error);
            }
        }
        #endregion

        #region Event Handlers
        void fileCreatedOrChanged(object sender, sysIO.FileSystemEventArgs e)
        {
            try
            {
                WriteToEventLog("Enter fileCreatedOrChanged", EventLogEntryType.Information);

                if (!_queue.Contains(e.FullPath))
                    _queue.Enqueue(e.FullPath);
                if (!_isDequeueing)
                    DeQueue();
            }
            catch (Exception ex)
            {
                WriteToEventLog(ex, EventLogEntryType.Error);
            }
        }
        #endregion

        #region Do work on another Thread
        void BackgroundWorkerDoWork(object sender, DoWorkEventArgs e)
        {
            try
            {
                WriteToEventLog("Enter BackgroundWorkerDoWork", EventLogEntryType.Information);
                BackgroundWorker bw = sender as BackgroundWorker;

                WriteToEventLog("Create Handler", EventLogEntryType.Information);
                RivWorks.FeedHandler.Library.Handler handler = new RivWorks.FeedHandler.Library.Handler(Convert.ToBoolean(AppSettings.Default.InProduction), AppSettings.Default.ArchivePath);

                WriteToEventLog("Setup Handler", EventLogEntryType.Information);
                handler.Keys = _keys;
                handler.RootDirectory = AppSettings.Default.RootDirectory;
                handler.FtpPath = AppSettings.Default.FTPRootPath;
                handler.WorkPath = AppSettings.Default.WorkPath;
                handler.ArchivePath = AppSettings.Default.ArchivePath;
                handler.EmailHost = AppSettings.Default.EmailHost;
                handler.EmailPassword = AppSettings.Default.EmailPassword;
                handler.EmailUser = AppSettings.Default.EmailUser;
                handler.ErrorNotificationRecipients = AppSettings.Default.ErrorNotificationRecipients;
                handler.InProduction = Convert.ToBoolean(AppSettings.Default.InProduction);

                Library.DTO.FileHandler fileHandler = new Library.DTO.FileHandler(handler.FtpPath, handler.WorkPath, handler.ArchivePath, (string)e.Argument);

                WriteToEventLog("Call Handler.Execute", EventLogEntryType.Information);
                handler.Execute(bw, e, fileHandler);
            }
            catch (Exception ex)
            {
                WriteToEventLog(ex, EventLogEntryType.Error);
            }
            finally
            {
                WriteToEventLog("Exit BackgroundWorkerDoWork", EventLogEntryType.Information);
            }
        }
        void BackgroundWorkerProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            try
            {
                if (e.ProgressPercentage >= 100)
                {
                }
            }
            catch (Exception ex)
            {
                WriteToEventLog(ex, EventLogEntryType.Error);
            }
        }
        void BackgroundWorkerRunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            try
            {
                if (e.Cancelled)
                {
                    WriteToEventLog("Cancelled.", EventLogEntryType.Warning);
                    if (e.Error != null)
                    {
                        WriteToEventLog(e.Error, EventLogEntryType.Error);
                    }
                }
                else if (e.Error != null)
                {
                    WriteToEventLog(e.Error, EventLogEntryType.Error);
                }
                else
                {
                    WriteToEventLog("Successfully completed.", EventLogEntryType.Information);
                }
            }
            catch (Exception ex)
            {
                WriteToEventLog(ex, EventLogEntryType.Error);
            }
        }
        #endregion

        #region Private Methods
        private void Tick(object data)
        {
            try
            {
                if (!_isDequeueing)
                {
                    WriteToEventLog("Enter Tick.  FTP Root = " + AppSettings.Default.FTPRootPath, EventLogEntryType.Information);

                    foreach (string key in _keys)
                    {
                        List<string> files = Directory.GetFiles(Path.Combine(AppSettings.Default.FTPRootPath), "*." + key, SearchOption.AllDirectories).ToList();
                        foreach (string fileName in files)
                        {
                            if (File.Exists(fileName))
                            {
                                // Toss this file name into the Queue...
                                WriteToEventLog("Call _queue.Enqueue(" + fileName + ")", EventLogEntryType.Information);
                                if (!_queue.Contains(fileName))
                                    _queue.Enqueue(fileName);
                            }
                        }
                    }
                    // Now, start handling the list of files...
                    DeQueue();
                }
            }
            catch (Exception ex)
            {
                WriteToEventLog(ex, EventLogEntryType.Error);
            }
            finally
            {
                WriteToEventLog("Exit Tick", EventLogEntryType.Information);
            }
        }
        private void DeQueue()
        {
            try
            {
                _isDequeueing = true;

                WriteToEventLog("Enter DeQueue", EventLogEntryType.Information);

                while (_queue.Count > 0)
                {
                    string queuedFile = _queue.Dequeue();
                    WriteToEventLog("DeQueued " + queuedFile, EventLogEntryType.Information);

                    bool isValid = false;
                    foreach (string key in _keys)
                    {
                        if (Path.GetExtension(queuedFile).Replace(".", "").Equals(key, StringComparison.CurrentCultureIgnoreCase))
                            isValid = true;
                    }

                    if (isValid)
                    {
                        // Now, spin up a new thread and do the work on the file, based on file type...
                        WriteToEventLog("Call RunWorkerAsync", EventLogEntryType.Information);
                        string UserName = Path.GetDirectoryName(queuedFile).Replace(AppSettings.Default.FTPRootPath, "").Replace("\\", "");
                        int i = 0;
                        DateTime sTime = DateTime.Now;
                        DateTime eTime = DateTime.Now;
                        _worker.RunWorkerAsync(queuedFile);  // goes to BackgroundWorkerDoWork(object sender, DoWorkEventArgs e) //

                        while(_worker.IsBusy)
                        {
                            System.Threading.Thread.Sleep(5000);
                            i++;
                        }
                        eTime = DateTime.Now;
                        TimeSpan ts = new TimeSpan(eTime.Ticks - sTime.Ticks);
                        string msg = String.Format("Import for {0} started at {1} and ended at {2}.  It took {3} cycles and the elapsed time was {4}:{5}:{6}.", UserName, sTime, eTime, i, ts.Hours, ts.Minutes, ts.Seconds);
                        WriteToEventLog(msg, EventLogEntryType.Information);
                    }
                }
            }
            catch (Exception ex)
            {
                WriteToEventLog(ex, EventLogEntryType.Error);
            }
            finally
            {
                _isDequeueing = false;
                WriteToEventLog("Exit DeQueue", EventLogEntryType.Information);
            }
        }
        private void WriteToEventLog(Exception ex, EventLogEntryType eventLogEntryType)
        {
            try
            {
                string message = string.Empty;
                string sTrace = ex.StackTrace;
                while (ex != null)
                {
                    message = message + Environment.NewLine + Environment.NewLine + ex.Message;
                    ex = ex.InnerException;
                }
                message = message + Environment.NewLine + Environment.NewLine + sTrace;

                WriteToEventLog(message, eventLogEntryType);
            }
            catch (Exception ex2)
            {
                WriteToEventLog(ex2.Message, EventLogEntryType.Error);
            }
        }
        private void WriteToEventLog(string message, EventLogEntryType eventLogEntryType)
        {
            try
            {
                this.EventLog.WriteEntry(message, eventLogEntryType);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        #endregion
    }
}

2010-10-20 - ПРИМЕЧАНИЕ. - Добавлен файл кода сервиса. Может быть, здесь есть элементарная ошибка?

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.IO;
using sysIO = System.IO;
using RivWorks.FeedHandler;

namespace RivWorks.FeedHandler.Service
{
    public partial class FeedListener : ServiceBase
    {
        #region Declarations
        private List<string> _keys = new List<string>();
        private System.Threading.Timer _clock = null;
        private FileSystemWatcher _watcher;
        private BackgroundWorker _worker;
        static private bool _isBusy = false;
        #endregion

        #region Constructor
        public FeedListener()
        {
            InitializeComponent();
        }
        #endregion

        #region Start/Stop
        protected override void OnStart(string[] args)
        {
            try
            {
                _keys.AddRange(new string[] { "csv", "xml", "zip", "rivx" });

                _worker = new BackgroundWorker();
                _worker.WorkerReportsProgress = true;
                _worker.WorkerSupportsCancellation = true;
                _worker.DoWork += new DoWorkEventHandler(BackgroundWorkerDoWork);
                _worker.ProgressChanged += new ProgressChangedEventHandler(BackgroundWorkerProgressChanged);
                _worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(BackgroundWorkerRunWorkerCompleted);

                _watcher = new FileSystemWatcher(AppSettings.Default.FTPRootPath, "*.*");
                _watcher.IncludeSubdirectories = true;
                _watcher.NotifyFilter = sysIO.NotifyFilters.DirectoryName | sysIO.NotifyFilters.FileName | sysIO.NotifyFilters.LastAccess | sysIO.NotifyFilters.CreationTime | sysIO.NotifyFilters.LastWrite;
                _watcher.Created += new sysIO.FileSystemEventHandler(fileCreatedOrChanged);
                _watcher.Changed += new sysIO.FileSystemEventHandler(fileCreatedOrChanged);
                _watcher.EnableRaisingEvents = true;

                // check every 5 minutes...
                _clock = new System.Threading.Timer(Tick, null, 0, 300000);
            }
            catch (Exception ex)
            {
                WriteToEventLog(ex, EventLogEntryType.Error);
                this.Stop();
            }
        }
        protected override void OnStop()  
        {
            try
            {
                _watcher.Dispose();
                _watcher = null;
                _clock.Dispose();
                _clock = null;
                _worker.Dispose();
                _worker = null;
            }
            catch (Exception ex)
            {
                WriteToEventLog(ex, EventLogEntryType.Error);
            }
        }
        #endregion

        #region Event Handlers
        void fileCreatedOrChanged(object sender, sysIO.FileSystemEventArgs e)
        {
            try
            {
                DTO.BackgroundWorkerEventArgs eventArgs = new DTO.BackgroundWorkerEventArgs();
                sysIO.WatcherChangeTypes myType = e.ChangeType;

                bool isValid = false;
                foreach (string key in _keys)
                {
                    if (Path.GetExtension(e.FullPath).Replace(".", "").Equals(key, StringComparison.CurrentCultureIgnoreCase))
                        isValid = true;
                }

                if (isValid)
                {
                    eventArgs.PathAndFile = e.FullPath;
                    eventArgs.Key = Path.GetExtension(e.FullPath).ToLower().Replace(".", "");
                    eventArgs.FileName = Path.GetFileName(e.FullPath);
                    eventArgs.Path = Path.GetDirectoryName(e.FullPath);
                    eventArgs.UserName = Path.GetDirectoryName(e.FullPath).Replace(AppSettings.Default.FTPRootPath, "").Replace("\\", "");
                    eventArgs.IsRunning = true;

                    System.Threading.Thread.Sleep(30000);

                    // Now, spin up a new thread and do the work on the file, based on file type...
                    _isBusy = true;
                    _worker.RunWorkerAsync(eventArgs);  // goes to BackgroundWorkerDoWork(object sender, DoWorkEventArgs e) //
                    int i = 0;
                    DateTime sTime = DateTime.Now;
                    DateTime eTime = DateTime.Now;
                    while (_isBusy)
                    {
                        System.Threading.Thread.Sleep(5000);
                        i++;
                    }
                    eTime = DateTime.Now;
                    TimeSpan ts = new TimeSpan(eTime.Ticks - sTime.Ticks);
                    string msg = String.Format("Import for {0} started at {1} and ended at {2}.  It took {3} cycles and the elapsed time was {4}:{5}:{6}.", eventArgs.UserName, sTime, eTime, i, ts.Hours, ts.Minutes, ts.Seconds);
                    WriteToEventLog(msg, EventLogEntryType.Information);
                }
            }
            catch (Exception ex)
            {
                WriteToEventLog(ex, EventLogEntryType.Error);
            }
        }
        #endregion

        #region Do work on another Thread
        void BackgroundWorkerDoWork(object sender, DoWorkEventArgs e)
        {
            try
            {
                RivWorks.FeedHandler.Handler handler = new RivWorks.FeedHandler.Handler();
                BackgroundWorker bw = sender as BackgroundWorker;

                handler.Execute(bw, e);
            }
            catch (Exception ex)
            {
                WriteToEventLog(ex, EventLogEntryType.Error);
            }
            finally
            {
                _isBusy = false;
            }
        }
        void BackgroundWorkerProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            try
            {
                if (e.ProgressPercentage >= 100)
                {
                    _isBusy = false;
                }
            }
            catch (Exception ex)
            {
                WriteToEventLog(ex, EventLogEntryType.Error);
            }
        }
        void BackgroundWorkerRunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            try
            {
                if (e.Cancelled)
                {
                    WriteToEventLog("Cancelled.", EventLogEntryType.Warning);
                    if (e.Error != null)
                    {
                        WriteToEventLog(e.Error, EventLogEntryType.Error);
                    }
                }
                else if (e.Error != null)
                {
                    WriteToEventLog(e.Error, EventLogEntryType.Error);
                }
                else
                {
                    WriteToEventLog("Successfully completed.", EventLogEntryType.Information);
                }
                _isBusy = false;
            }
            catch (Exception ex)
            {
                WriteToEventLog(ex, EventLogEntryType.Error);
            }
        }
        #endregion

        #region Private Methods
        private void Tick(object data)
        {
            try
            {
                foreach (string key in _keys)
                {
                    List<string> files = Directory.GetFiles(Path.Combine(AppSettings.Default.FTPRootPath), "*." + key, SearchOption.AllDirectories).ToList();
                    foreach (string fileName in files)
                    {
                        System.Threading.Thread.Sleep(5000);
                        if (File.Exists(fileName))
                        {
                            DateTime lat = File.GetLastWriteTime(fileName);
                            try
                            {
                                File.SetLastWriteTime(fileName, DateTime.Now);
                            }
                            catch
                            {
                                // just catch and ignore with a short pause...
                                System.Threading.Thread.Sleep(5000);
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                WriteToEventLog(ex, EventLogEntryType.Error);
            }
        }
        private void WriteToEventLog(Exception ex, EventLogEntryType eventLogEntryType)
        {
            try
            {
                string message = string.Empty;
                string sTrace = ex.StackTrace;
                while (ex != null)
                {
                    message = message + Environment.NewLine + Environment.NewLine + ex.Message;
                    ex = ex.InnerException;
                }
                message = message + Environment.NewLine + Environment.NewLine + sTrace;

                this.EventLog.WriteEntry(message, eventLogEntryType);
            }
            catch (Exception ex2)
            {
                WriteToEventLog(ex2, EventLogEntryType.Error);
            }
        }
        private void WriteToEventLog(string message, EventLogEntryType eventLogEntryType)
        {
            try
            {
                this.EventLog.WriteEntry(message, eventLogEntryType);
            }
            catch (Exception ex)
            {
                WriteToEventLog(ex, EventLogEntryType.Error);
            }
        }
        #endregion
    }
}

Ответы [ 2 ]

5 голосов
/ 20 октября 2010

Даже несмотря на то, что он работает как выпускная версия, вам все равно будет предоставлена ​​возможность подключиться к отладчику при сбое приложения ... вы просто не увидите символы отладки, просто сборка:)

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

Шаги, чтобы отключить доктора Ватсона здесь:
http://support.microsoft.com/kb/188296

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

НТН, Джеймс


* Редактировать * Исходя из предоставленного вами кода, я рассмотрю следующие области:

  1. Правильно ли установлен AppSettings.Default.FTPRootPath в App.Config?

  2. Есть ли какие-либо изменения, происходящие с этим каталогом сразу после запуска службы? У вас есть таймер с комментариями «проверять каждые пять минут», что немного сбивает с толку, потому что FileSystemWatcher начнет получать события, как только вы установите для EnableRaisingEvents значение true. Таким образом, проблема может лежать в пределах fileCreatedOrChanged

  3. Вдоль этих строк у вас есть один BackgroundWorker, обслуживающий несколько событий, и, что еще хуже, вы запускаете обработчик асинхронно. Это, скорее всего, мое подозрение, потому что если вы снова наберете _worker.RunWorkerAsync() во время выполнения первого задания, вы получите InvalidOperationException. Хотя я не уверен, почему вы не увидите этого в журнале

  4. Вы используете таймер для обновления времени последней записи для всех файлов в просматриваемой директории, и вы делаете это каждые пять секунд. Это кажется очень плохой идеей ... Я не уверен, что вы пытаетесь достичь. Это запустит ваше измененное событие FileSystemWatcher, которое объяснит, почему вы потерпели крах менее чем через 10 секунд после запуска (начальный тик таймера настроен на немедленное срабатывание, то есть через пять секунд вы меняете все времена файла вызывая FileSystemWatcher несколько раз вскоре после этого)

Так что я думаю, что в течение пяти секунд вы начали использовать несколько RunWorkAsync() вызовов для одного и того же BackgroundWorker, что является "нет-нет":)

Установка статической переменной _isBusy в значение true / false не является надежной, поскольку вы используете многопоточность с помощью BackgroundWorkers ... вам нужно использовать Mutex или какую-либо другую блокировку, но это на самом деле не противоречит цели используя BackgroundWorker?

Кроме того, если вы хотите использовать что-то вроде флага isBusy, оно должно выглядеть примерно так:

while (_isBusy) {
    System.Threading.Thread.Sleep(5000);
}

_isBusy = true;
_worker.RunWorkerAsync(eventArgs);

Вам нужно, чтобы значение _isBusy было ложным, прежде чем пытаться запустить Фоновый рабочий ... как у вас есть, если событие запускается 100 раз, вы сделаете 100 вызовов.

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

Возможно, вы сможете положиться на встроенное свойство BackgroundWorker.IsBusy, но, опять же, мне придется усомниться в преимуществах асинхронной потоковой обработки, если вы просто собираетесь блокировать, пока не завершится фоновый рабочий.


** Редактировать **

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

Я немного сбился с пути из-за растущей сложности ... вся эта очередь / очередь может быть ненужной. Или, может быть, я просто не вижу потребности, которая действительно существует. Опять же, меня поразило то, что вы запускаете фоновый рабочий асинхронно, а затем переводите основной поток в спящий режим до его завершения.

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

Но код, который вы просили! По сути, куда бы вы ни решили позвонить _worker.RunWorkerAsync(queuedFile), вместо того, чтобы запускать один класс BackgroundWorker, каждый раз создавайте новый. Передайте все те же параметры для обработчиков событий и т. Д. Ваша точка входа в службу отбросит все ссылки BGW и будет выглядеть так:

protected override void OnStart(string[] args)
{
    try
    {
        _keys.AddRange(new string[] { "csv", "xml", "zip", "rivx" });

        _watcher = new FileSystemWatcher(AppSettings.Default.FTPRootPath, "*.*");
        _watcher.IncludeSubdirectories = true;
        _watcher.NotifyFilter = sysIO.NotifyFilters.DirectoryName | sysIO.NotifyFilters.FileName | sysIO.NotifyFilters.LastAccess | sysIO.NotifyFilters.CreationTime | sysIO.NotifyFilters.LastWrite;
        _watcher.Created += new sysIO.FileSystemEventHandler(fileCreatedOrChanged);
        _watcher.Changed += new sysIO.FileSystemEventHandler(fileCreatedOrChanged);
        _watcher.EnableRaisingEvents = true;

        WriteToEventLog("Exit Start", EventLogEntryType.Information);
    }

и код, где вы запускаете BGW асинхронно, станет:

BackgroundWorker worker = new BackgroundWorker();
worker.WorkerReportsProgress = true;
worker.WorkerSupportsCancellation = true;
worker.DoWork += new DoWorkEventHandler(BackgroundWorkerDoWork);
worker.ProgressChanged += BackgroundWorkerProgressChanged;        // Note you don't need
worker.RunWorkerCompleted += BackgroundWorkerRunWorkerCompleted;  // the 'new' here

worker.RunWorkerAsync(queuedFile);  // goes to BackgroundWorkerDoWork(object sender, DoWorkEventArgs e) //
0 голосов
/ 20 октября 2010

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

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

...