asynchronous design pattern and event

M

marian.kovac

Hi, I have this simple sample code:

class SearchRange
{
static int m = 0;
static void Main(string[] args)
{
Discover discover = new Discover();

// Add discovered device handler
discover.DiscoverUpdate += DiscoveredDeviceCallback;

// Add progress handler
discover.ProgressUpdate += ProgressCallback;

Console.WriteLine("Discovered devices:");

// Start searching for devices
IAsyncResult ar = discover.BeginSearchRange("193.93.73.180",
"193.93.73.190",
1000, CompletedCallback, null);

discover.EndSearchRange(ar);

Result result;
DiscoveredDevice discoveredDevice = discover.EndSearchAddress(ar,
out result);

Console.WriteLine("\nResult: {0}", result.Status);
if (discoveredDevice != null)
Console.WriteLine("Discovered device: {0}\n",
discoveredDevice.Name);
}

private static void DiscoveredDeviceCallback(object sender,
DiscoverEventArgs e)
{
DiscoveredDevice device = e.DiscoveredDevice;
Console.WriteLine("{0} {1} {2}", device.SerialNumber,
device.IPAddress, device.Name);
}

private static void ProgressCallback(object sender, ProgressEventArgs
e)
{
Console.WriteLine("Progress: {0}%", e.Progress);
Thread.Sleep(300);
}

private static void CompletedCallback(IAsyncResult ar)
{
Console.WriteLine("Completed Callback!\n");
}
}

class Discover is implemented as asynchronous design pattern
(asynchronous methods are BeginSearchAddress, EndSearchAddress).
ProgressCallback is callback for event ProgressUpdate. That code has
the correct progress output (e.g. 20% 30% ... 100%) if
Thread.Sleep(300) is commented else program get bad progress output
(e.g. 20% 30% ... 100% 60%). I know that CompletedCallback is called
when the request (BeginSearchAddress) is completed, and the EndRequest
call will wait until the request is complete and return the result.
Those are know things. And what event? Does the event [event callback]
need in the class implemented as asynchronous design pattern special
handling of the itself code? Where can I found information about this
problem? Thanks and best regards

Marian.
 
P

Peter Duniho

Hi, I have this simple sample code:

It coule be simpler, IMHO. And at the same time, it could be more
detailed (you left out the class that does all of the interesting things).

But even so...
[...] That code has
the correct progress output (e.g. 20% 30% ... 100%) if
Thread.Sleep(300) is commented else program get bad progress output
(e.g. 20% 30% ... 100% 60%).

From that behavior, it strongly suggests to me that you are not doing
anything to order the progress update calls. In particular, you are
probably simply having an arbitrary thread (either a new thread, or
choosing a new thread pool thread for each update) execute the delegate.
Perhaps by calling delegate.BeginInvoke()?

You can't do this.

The BackgroundWorker, which does something similar, works because the
progress updates are all executed on the main GUI thread, in the order in
which they are raised. That ensures correct ordering for the updates.
You need to do something similar for your Discover class. Since you don't
have a GUI, you'll have to create your own queue to deal with this. You
can either consume the queue in your main thread (you're not doing
anything useful in the main thread at the moment anyway), or you can
create yet another thread to do that. The key is to make sure that only
one thread is consuming the queue of updates, and that it's always the
same thread.

Of course, it should go without saying that the queue elements should be
produced in order only by one thread as well. This would be the thread
that does the work in the Discover class, where the progress updates are
created.

Pete
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top