简体   繁体   English

BackgroundWorker如何工作?

[英]How does the BackgroundWorker work exactly?

I have written this code for a Message Receiving class that uses a backgroundworker to check for new files in a directory (the files are SMS messages received from users that are updating continuously). 我已经为使用后台工作人员检查目录中的新文件的Message Receiving类编写了此代码(这些文件是从用户那里接收的,不断更新的SMS消息)。 If the directory is not empty, I send an acknowledgement message to every new SMS and start the worker again. 如果目录不为空,我会向每个新的SMS发送确认消息,然后再次启动工作程序。

 public MessageReceiving()
    {
        bw.DoWork += new DoWorkEventHandler(bw_DoWork);
        bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);           
    }
void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {   
        if(e.Result == true)
        { 
        SendAcknowledgement();
        if(!bw.IsBusy)
            bw.RunWorkerAsync();
        }
    }

void bw_DoWork(object sender, DoWorkEventArgs e)
    {
       bool flag = false;
        while (flag.Equals(false))
        {
            string path = @"C:\SMS";
            if (Directory.GetFiles(path).Length > 0)
            {
                e.Result = true;
                flag = true;
            }
            else
            {
                e.Result = false;
            }
        }

    }

I initialize the worker from the main thread once - 我一次从主线程初始化worker-

MessageReceiving mr = new MessageReceiving();
mr.bw.RunWorkerAsync();

I did all this to allow me to send messages synchronously to users - As soon as a user send an SMS, I send him an ACK. 我做了所有这些工作,以允许我向用户同步发送消息-用户发送SMS时,我便立即向他发送ACK。 The problem is that the user is getting multiple ACKs even on sending one SMS - why is this happening? 问题在于,即使在发送一条SMS时,用户也会收到多个ACK-为什么会发生这种情况? I have thought of every possibility, but to no avail! 我已经想到了所有可能性,但无济于事!

Consider what happens when this starts: 考虑一下开始时会发生什么:

  • You start running bw_DoWork 您开始运行bw_DoWork
  • That then tight-loops (not a good idea to start with) until it finds a file 然后紧缩循环(开始时不是一个好主意),直到找到文件
  • The background worker completes, and you send an acknowledgement 后台工作人员完成,并且您发送了确认
  • You then immediately run the background worker again... which will find the file again unless you've deleted the file during SendAcknowledgement . 然后,您立即再次运行后台工作程序...,它将再次找到该文件,除非您在SendAcknowledgement期间删除了该文件。 Have you? 你呢?

I suspect what you really want instead of any of this is a FileSystemWatcher by the way. 怀疑您真正想要的不是FileSystemWatcher而不是任何东西。 Also note that just because a file is present doesn't mean that it's finished being written to yet, or that you can read it. 另外请注意,仅仅因为一个文件是否存在 ,并不意味着它的完成被写入呢,或者你可以读取它。

Additionally, your tight loop can be made a lot simpler: 此外,您的紧密循环可以简化很多:

void bw_DoWork(object sender, DoWorkEventArgs e)
{
    string path = @"C:\SMS";
    while (!e.Result)
    {
        e.Result = Directory.GetFiles(path).Any();
    }
}

and I would likewise change 我也会改变

if (e.Result == true)

to

if (e.Result)

(Assuming e.Result is typed as a bool ; if it's not, your current code has other problems.) (假设e.Result键入为bool ;如果不是,则您当前的代码还有其他问题。)

It depends on code not shown. 这取决于未显示的代码。

You need at most 1 thread scanning the files. 您最多需要1个线程扫描文件。 Then somewhere during the processing you have to remove or rename the files. 然后,在处理过程中的某处必须删除或重命名文件。 In your case this should happen in SendAcknowledgement, and the Bgw should not be restarted before it all replies have been sent. 在您的情况下,这应该在SendAcknowledgement中发生,并且在发送所有答复之前,不应重新启动Bgw。

It would be better to use a rename the files early and push them in a queue. 最好尽早使用重命名文件并将其放入队列。 Or process them directly after finding a file inside DoWork. 或在DoWork中找到文件后直接处理它们。 SendAcknowledgement(fileName) looks more logical. SendAcknowledgement(fileName)看起来更合逻辑。

Currently your SendAcknowledgement() runs in the main thread, that may not be what you want. 当前,您的SendAcknowledgement()在主线程中运行,这可能不是您想要的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM