我为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 - 为什么会这样?我已经想到了各种可能性,但无济于事!
答案 0 :(得分:2)
考虑一下这种情况会发生什么:
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()
在主线程中运行,可能不是您想要的。