Asynchronous Design Pattern

L

Leslie Sanford

I'm thinking about using the design pattern described at the link below
to solve a problem:

http://msdn2.microsoft.com/en-us/library/ms228963.aspx

I have a question, though, and would appreciate any help.

The pattern describes using BeginOperationName and EndOperationName
methods for asynchronous operations, where "OperationName" represents
the name of the operation to be invoked asynchronously. For example, say
you want to read from a Stream asynchronously. You would call BeginRead,
passing it an AsyncCallback delegate and possibly an object representing
state information. At some point, the stream invokes your callback. In
your callback, you call EndRead, passing it the IAsyncResult object
given to you to get the result of the read operation.

Ok, say we are writing a class to implement this pattern. Instread of
reading bytes, we're reading an object of some type. Let's call the
class ObjectReader. We have the methods BeginReadObject and
EndReadObject. Like the Stream class, this class has a Close method that
disposes of the object.

Where it gets fuzzy for me is trying to figure out what should happen
when the BeginReadObject method is called and the ObjectReader's Close
method is called before the specified callback is invoked.

My thought is that in response to being closed, the ObjectReader should
invoke any awaiting callbacks. When the callback calls EndObjectRead, it
returns null indicating that no more objects are available to be read.
Once all awaiting callbacks have been invoked, the ObjectReader finishes
closing down. At this point, it is officially closed; any attempt to
read from the ObjectReader will throw an ObjectDisposedException.

For BeginReadObject operations that were invoked without a callback,
i.e. null was passed instead of a delegate for the callback parameter,
the wait handles of any remaining IAsyncResult objects are set when the
ObjectReader is closed. Calls to EndReadObject behave just as they would
inside the callback.

Any thoughts?
 
G

Guest

re:


:


RE:
My thought is that in response to being closed, the ObjectReader should
invoke any awaiting callbacks. When the callback calls EndObjectRead, it
returns null indicating that no more objects are available to be read.
Once all awaiting callbacks have been invoked, the ObjectReader finishes
closing down. At this point, it is officially closed; any attempt to
read from the ObjectReader will throw an ObjectDisposedException.

Hmm.. to an end user of your code returning null is an ambigous way of
communicating your intention and probably cause me to get a a null reference
exception that might lead me down the path of examining what I'm passing to
you as to make sure thier values are valid. I'd much rather get an exception
that tells me what the problem is. I'm thinking of something similar to how
the SqlDataReader will throw an InvalidOperationException w/ the message "
Invalid attempt to Read when reader is closed."

Stream Example:
IAsyncResult result = stream.BeginRead( _data, 0,length, cb, null );
// stream.Close(); calling Close yields an IOException, "The handle is
invalid."
result = null;

private void cb( IAsyncResult result ) {
int numberOfBytesRead = _stream.EndRead( result );
//when the above runs after the call to close the result is multiple
ArgrumentExceptions "EndRead can only be called once for each asynchronous
operation "
_stream.Dispose();
Array.Resize<byte>( ref _data, numberOfBytesRead );
if (_callBack != null) {
_callBack(this._numRead, _path, this._data);
}
}
 
L

Leslie Sanford

Chris Mohan said:
:

RE:

Hmm.. to an end user of your code returning null is an ambigous way of
communicating your intention and probably cause me to get a a null
reference exception that might lead me down the path of examining what
I'm passing to you as to make sure thier values are valid. I'd much
rather get an exception that tells me what the problem is. I'm
thinking of something similar to how the SqlDataReader will throw an
InvalidOperationException w/ the message "Invalid attempt to Read when
reader is closed."

The problem I have with throwing an exception is that calling EndRead on
a stream after it has been closed does not in itself cause an exception
to be raised.

Hmm, the Stream's BeginRead method takes a byte array buffer for reading
the value into. So in my hypothetical ObjectReader class, I could have
it's BeginReadObject method take an array of the object type it's
suppose to be reading. Objects read would be placed in this array. When
EndReadObject is called, it can return the number of objects read. It
can behave exactly like the Stream class.
 

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