【问题标题】:backgroundworker RunWorkerCompleted not firing "sometimes"backgroundworker RunWorkerCompleted 不触发“有时”
【发布时间】:2014-03-18 06:03:15
【问题描述】:

我有一个文件系统观察器,它在发生更改时检查文件。这连续运行了 4 次,但第 5 次尝试未关闭 formwaitingform 并且未调用 backgroundWorker1_RunWorkerCompleted。我尝试删除打开和关闭繁忙表单的代码,然后代码按预期运行,所以看起来这就是问题所在。我的错误捕获没有错误,但怀疑该问题与 filesystwatcher 在不同线程中触发有关并且无法关闭繁忙的表格,但我不确定。任何帮助表示赞赏。

    public partial class Main : Telerik.WinControls.UI.RadForm, IMessageFilter
    {

        WaitingForm formWaitingForm;
        BackgroundWorker bw = new BackgroundWorker(); // Backgroundworker
        public Main()
        {
......

public void OnChanged(object sender, FileSystemEventArgs e)
        {
            try
            {
                // Do not add logging before first line as we want to set the event change immediately to endure multiple events are not fired for 
                // multiple changes simultaneously


                if (MyGlobals.LastFired.Add(TimeSpan.FromSeconds(1)) < DateTime.UtcNow) //http://stackoverflow.com/questions/22236363/filesystemwatcher-for-a-list-of-files/22236688#22236688
                {
                    MyGlobals.LastFired = DateTime.UtcNow;
                    Logging.Write_To_Log_File("Entry", MethodBase.GetCurrentMethod().Name, "", "", "", "", "", "", 1); // See comment inside try
                    System.Threading.Thread.Sleep(2000);
                    Logging.Write_To_Log_File("Item change detected " + e.ChangeType + " " + e.FullPath + " " + e.Name, MethodBase.GetCurrentMethod().Name, "", "", "", "", "", "", 2);


                    MyGlobals.watchers.Clear();
                    foreach (FileSystemWatcher element in MyGlobals.watchers)
                    {
                        element.EnableRaisingEvents = false;
                    }
                    CheckFilesAsync(); // Get the timer to execute immediately

                }
                else
                {
                    Logging.Write_To_Log_File("Change within the time limit", MethodBase.GetCurrentMethod().Name, "", "", "", "", "", "", 1);
                }




                //Logging.Write_To_Log_File("Exit", MethodBase.GetCurrentMethod().Name, "", "", "", "", "", "", 1);
                return;

            }


            catch (Exception ex)
            {
                // If exception happens, it will be returned here
                Logging.Write_To_Log_File("Error", MethodBase.GetCurrentMethod().Name, "", "", ex.ToString(), "", "", "", 2);
            }

            finally
            {
                foreach (FileSystemWatcher element in MyGlobals.watchers)
                {
                    element.EnableRaisingEvents = true;
                }
            }


        }


 private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            try
            {
                Logging.Write_To_Log_File("Entry", MethodBase.GetCurrentMethod().Name, "", "", "", "", "", "", 1);
                lock (MyGlobals._object) // Lock for threadsafe operations
                {

                    // First, handle the case where an exception was thrown. 
                    if (e.Error != null)
                    {
                        RadMessageBox.Show(this, e.Error.Message, "Error", MessageBoxButtons.OK, RadMessageIcon.Error);
                        Logging.Write_To_Log_File(e.Error.Message, MethodBase.GetCurrentMethod().Name, "", "", "", "", "", "", 2);

                    }
                    else if (e.Cancelled)
                    {
                        // Next, handle the case where the user canceled the operation. 
                        RadMessageBox.Show(this, "Background task cancelled", "Cancel", MessageBoxButtons.OK, RadMessageIcon.Error);
                        Logging.Write_To_Log_File("Task cancelled", MethodBase.GetCurrentMethod().Name, "", "", "", "", "", "", 1);
                    }
                    else
                    {
                        // Finally, handle the case where the operation succeeded.

                        Logging.Write_To_Log_File("Finished background worker - closing Form", MethodBase.GetCurrentMethod().Name, "", "", "", "", "", "", 1);

                        this.BeginInvoke((MethodInvoker)(() => formWaitingForm.Close()));
                        this.BeginInvoke((MethodInvoker)(() => formWaitingForm.Dispose()));
                        //formWaitingForm.Close();
                        //formWaitingForm.Dispose();
                        Logging.Write_To_Log_File("Form closed", MethodBase.GetCurrentMethod().Name, "", "", "", "", "", "", 1);

                    }
                   // _timer.Enabled = true;
                }
                Logging.Write_To_Log_File("Exit", MethodBase.GetCurrentMethod().Name, "", "", "", "", "", "", 1);
            }
            catch (Exception ex)
            {
                // If exception happens, it will be returned here
                Logging.Write_To_Log_File("Error", MethodBase.GetCurrentMethod().Name, "", "", ex.ToString(), "", "", "", 2);
            }



        }

【问题讨论】:

标签: c# backgroundworker filesystemwatcher


【解决方案1】:

文件系统观察程序在文件更改时引发事件 - 我想触发 CheckFilesAsync,然后打开一个繁忙的表单,最后关闭这个表单。如下所示在主线程中调用 Checkfilesasync 解决了我的问题。

   this.BeginInvoke((MethodInvoker)(() => CheckFilesAsync())); // Check files in the Main thread otherwise threading issues occur

【讨论】:

    猜你喜欢
    • 2011-11-29
    • 1970-01-01
    • 1970-01-01
    • 2011-02-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-08
    相关资源
    最近更新 更多