Backgroundworker 关于后台工作程序的实现/使用

Backgroundworker 关于后台工作程序的实现/使用,backgroundworker,multiple-instances,Backgroundworker,Multiple Instances,好的,我已经到处找了找,找不到一个合适的答案来回答我的问题。我有一个相当复杂的代码库,它使用一个计时器来启动后台工作程序的创建,以便定期传输某些内容 当它调用ReportProgress时,我遇到了一个问题: “此操作已调用OperationCompleted,进一步调用是非法的。” 堆栈跟踪: at System.ComponentModel.AsyncOperation.VerifyNotCompleted() at System.ComponentModel.AsyncOperation.

好的,我已经到处找了找,找不到一个合适的答案来回答我的问题。我有一个相当复杂的代码库,它使用一个计时器来启动后台工作程序的创建,以便定期传输某些内容

当它调用ReportProgress时,我遇到了一个问题: “此操作已调用OperationCompleted,进一步调用是非法的。”

堆栈跟踪:

at System.ComponentModel.AsyncOperation.VerifyNotCompleted()
at System.ComponentModel.AsyncOperation.Post(SendOrPostCallback d, Object arg)
at System.ComponentModel.BackgroundWorker.ReportProgress(Int32 percentProgress, Object userState)
at NAME.TX.Work(Object sender, DoWorkEventArgs e) in file.cs:line 68
at System.ComponentModel.BackgroundWorker.OnDoWork(DoWorkEventArgs e)
at System.ComponentModel.BackgroundWorker.WorkerThreadStart(Object argument)
我的问题相对简单,计时器关闭时调用的函数会创建一个新的后台工作程序,但它实际上是一个新的后台工作程序吗?

我的代码(由于非常庞大而简化):


Work函数是一个覆盖函数,因为有一个更高的处理类允许传输和接收,这两个类继承自同一个类,因此我可以使用通用的ReportProgress和Close方法。

在黑暗中拍摄。。。在创建BGW的线程上调用BGW ProgressChanged回调。在您的情况下,这也是一个后台线程,因为您是在计时器回调上创建它的(除非您使用的是System.Windows.Forms.timer或System.Timers.timer和SynchronizationObject)。在调用ReportProgress()时,线程是否有可能被杀死?@Charles:有道理,我在开始研究它之后也在想同样的事情。。。现在我的问题是,实施它的最佳方式是什么?我想知道我是否可以通过线程池更有效地工作。当然,我会遇到来回传递数据的问题,因为“主线程”关心通过ReportProgress传递的UserState对象。通常在Work()中,您会在某种循环中调用ReportProgress(),为percentProgress传递逐渐增大的值。有什么原因不能直接从计时器回调调用Work()?Work()可以直接调用Report()和Complete()。@Charles:嗯,在计时器开始工作之前,Work调用ReportProgress的原因是因为它给了我一种有效的方法,可以在不关闭BackgroundWorker的情况下将信息报告回前台线程。我可以这样做,但是现在我的问题有两个:1)如果计时器直接调用Work,Report()是否仍在前台线程中?这是怎么回事?2) 我不认为这个解决方案特别优雅,这就是为什么我现在想知道我是否应该采取一种新的方法。。。如果我有一个线程池,一个传输和一个定时器上的传输都将相同的函数放在工作队列上,那么该函数的状态将返回到前台线程中的一个公共对象。然后可以使用ManualReset向前台线程发送信号,使其退出状态队列。
//THIS IS THE FUNCTION CALLED BY TIMER
public void TransmitMSG(MSG msg)
{
        //Initialze _tx
        this.m_thread = new BackgroundWorker();
        m_thread.WorkerReportsProgress = true;

        //Initialize all events used by _tx
        m_thread.DoWork += new DoWorkEventHandler(this.Work);
        m_thread.ProgressChanged += new ProgressChangedEventHandler(this.Report);
        m_thread.RunWorkerCompleted += new RunWorkerCompletedEventHandler(this.Complete);

        //Run the backgroundworker
        m_thread.RunWorkerAsync(msg);
}

//THIS IS THE WORK FUNCTION
public override void Work(object sender, DoWorkEventArgs e)
    {
        //This code is in the TX Thread
        //The sender should be the a BackgroundWorker
        BackgroundWorker _tx = sender as BackgroundWorker;

        //Check the Argument
        if (e.Argument != null && e.Argument.GetType() == typeof(MSG))
        {
            //Transmit the Argument Message
            m_THING.Transmit((MSG)e.MSG)

            //Report progress according to the result
            _tx.ReportProgress(CONSTANTS.PROGRESS.SUCCESS_TX, (MSG)e.Argument);
        }
    }