BackgroundWorker如何正常工作?

时间:2011-07-27 05:18:08

标签: c# backgroundworker

我为Message Receiving类编写了此代码,该类使用后台工作程序检查目录中的新文件(这些文件是从连续更新的用户收到的SMS消息)。如果目录不为空,我会向每个新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;
            }
        }

    }

我从主线程初始化一次工作 -

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

我做了所有这些以允许我同步向用户发送消息 - 一旦用户发送短信,我就发送给他一个ACK。问题是即使发送一条短信,用户也会收到多个ACK - 为什么会这样?我已经想到了各种可能性,但无济于事!

2 个答案:

答案 0 :(得分:2)

考虑一下这种情况会发生什么:

  • 您开始运行bw_DoWork
  • 然后紧紧循环(不是一个好主意开始)直到找到文件
  • 后台工作人员完成,您发送确认
  • 然后,您再次立即运行后台工作程序...除非您在SendAcknowledgement期间删除了该文件,否则将再次找到该文件。你呢?

怀疑你真正想要的是什么而不是任何顺便说一句FileSystemWatcher。另请注意,仅仅因为文件存在并不意味着它已完成写入,或者您可以阅读它。

此外,您的紧密循环可以变得更简单:

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

我也会改变

if (e.Result == true)

if (e.Result)

(假设e.Result被输入为bool;如果不是,则您当前的代码还有其他问题。)

答案 1 :(得分:1)

这取决于未显示的代码。

您最多需要1个线程扫描文件。然后在处理过程中的某个地方你必须删除或重命名文件。在您的情况下,这应该发生在SendAcknowledgement中,并且在发送所有回复之前不应重新启动Bgw。

最好使用早期重命名文件并将它们推入队列中。或者在DoWork中找到文件后直接处理它们。 SendAcknowledgement(fileName)看起来更合乎逻辑。

目前您的SendAcknowledgement()在主线程中运行,可能不是您想要的。