首页 > 解决方案 > 班级内的后台工作人员,我必须等待再次运行

问题描述

我创建了一个后台工作者。我工作得很好......直到我不得不再次运行它。好像 CancelAsync 不是立即的,我必须等待。

这是我的工作流程,可帮助您了解我在做什么。

  1. 打开一个文件
  2. 创建一个包含我的后台工作逻辑的对象。它做了很多事情并写了一个文件。工人应立即结束、关闭或自毁。哈哈
  3. 在没有错误的情况下立即重复失败。但是,我目睹的行为是,如果我等待大约 10 秒并打开一个新文件来处理它就可以了。它只是不喜欢以正确的方式行事。

从我的主要形式。

private void Button_Click(object sender, RoutedEventArgs e)
{
    File_Worker myWorker = new File_Worker();
}

这是我的课

namespace Market.BI.Workers
{
    class File_Worker
    {
        private BackgroundWorker worker = new BackgroundWorker();

        void Worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {   
            Stuff
        }
        void Worker_DoWork(object sender, DoWorkEventArgs e)
        {
            var myItems      = new List<Part>();
            _CSV_Path        = "somefile.csv";
            var counter      = 1;
            var lineCount    = File.ReadLines(e.Argument.ToString()).Count();

            using (StreamReader reader = new StreamReader((string)e.Argument))
            {
                while (true)
                {
                    string line = reader.ReadLine();
                    if (line == null)
                    {
                        break;
                    }

                    String value     = line;
                    int startIndex   = 0;
                    int length       = 9;
                    String substring = value.Substring(startIndex, length);
                    if (substring == "UDI")
                    {
                        myItems.Add(new Part(line));   <<Part is a structured Class
                    }
                    ((BackgroundWorker)sender).ReportProgress(counter * 100 / lineCount);
                    counter = counter + 1;
                }
                reader.Close();
            }
        }
    e.Result = myItems;
        }
        void Worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            Stuff
            worker.CancelAsync();
        }

        //Method
        public File_Worker()
        {
            worker.DoWork               += new DoWorkEventHandler(Worker_DoWork);
            worker.ProgressChanged      += new ProgressChangedEventHandler(Worker_ProgressChanged);
            worker.RunWorkerCompleted   += new RunWorkerCompletedEventHandler(Worker_RunWorkerCompleted);
            worker.WorkerReportsProgress = true;
            worker.WorkerSupportsCancellation = true;
            worker.RunWorkerAsync();
            fileProgressBar.IsIndeterminate = false;
        }
    }
}

标签: c#.netwpf

解决方案


对于那些试图帮助我解决这个问题的人,谢谢。我不太确定我是否准确地回答了这个问题。我决定采用不同的方法通过使用 TPL 来解决我的问题。通过创建一个线程,我能够做完全相同的事情,包括更新我的进度条。

如果这将有助于任何人前进,这里有一些片段。

var ptx = new Task(() => DoWork(myWorker, fileProgressBar, gridPartEdgeDetails));
                    myWorker.file_Path = filePath;
                    ptx.Start(); 


static void DoWork(CVS_Worker x, ProgressBar pb, DataGrid dg)
{
    var parts = new List<Part>();
    parts     = x.DoMyStuff(pb);  //pass in my progressbar

    //Update Datagrid
    dg.Dispatcher.Invoke(() =>
    {
        dg.ItemsSource = parts;
    });
} 

在我的 CVS_Worker 类中,我从那里调用了我的状态栏。最后,编码更简单,我可以在没有任何问题的情况下连续多次启动这个过程。

pb.Dispatcher.Invoke(() =>
{
    pb.Value = (counter * 100 / lineCount);
});

推荐阅读