BackgroundWorker到底是如何工作的
本文关键字:工作 何工作 BackgroundWorker | 更新日期: 2023-09-27 18:03:53
我为Message Receiving类编写了这段代码,该类使用后台工作者检查目录中的新文件(这些文件是从不断更新的用户接收到的SMS消息)。如果目录不为空,我将向每个新SMS发送确认消息并再次启动worker。
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();
我所做的一切都是为了让我能够同步地向用户发送消息——一旦用户发送了一条SMS,我就会向他发送一个ACK。问题是用户即使发送一条短信也会收到多个ack -为什么会发生这种情况?所有的可能性我都想过了,但都无济于事!
考虑当它开始时会发生什么:
- 开始运行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个线程扫描文件。然后在处理过程中的某个地方,您必须删除或重命名文件。在您的情况下,这应该发生在SendAcknowledgement中,并且在发送所有回复之前不应该重新启动Bgw。
最好尽早使用重命名文件并将它们放入队列中。或者在DoWork中找到文件后直接处理它们。SendAcknowledgement(fileName)
看起来更符合逻辑。
当前你的SendAcknowledgement()
运行在主线程中,这可能不是你想要的。