Reputation: 87
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). If the directory is not empty, I send an acknowledgement message to every new SMS and start the worker again.
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 -
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. The problem is that the user is getting multiple ACKs even on sending one SMS - why is this happening? I have thought of every possibility, but to no avail!
Upvotes: 1
Views: 942
Reputation: 273854
It depends on code not shown.
You need at most 1 thread scanning the files. 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.
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. SendAcknowledgement(fileName)
looks more logical.
Currently your SendAcknowledgement()
runs in the main thread, that may not be what you want.
Upvotes: 1
Reputation: 1504122
Consider what happens when this starts:
SendAcknowledgement
. Have you?I suspect what you really want instead of any of this is a FileSystemWatcher
by the way. 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.)
Upvotes: 2