I've noticed that the client-side DataPortalInvokeComplete event is not raised if a server-side DataPortalException is caught. The host application can know that a data portal operation is in progress but in the current situation cannot reliably know when the data portal operation is complete. I suggest putting the OnDataPortalInvokeComplete method calls in a finally block to ensure (as best as possible) that DataPortalInvoke/DataPortalInvokeComplete events always come in pairs.
Thanks for your consideration,
Mike
I understand the OnDataPortalException method to be a server-side method. I'm looking at the client side. Here's a code excerpt from DataPortal.Fetch:
OnDataPortalInvoke(new DataPortalEventArgs(dpContext));
try
{
result = proxy.Fetch(objectType, criteria, dpContext);
}
catch (Server.DataPortalException ex)
{
result = ex.Result;
if (proxy.IsServerRemote)
ApplicationContext.SetGlobalContext(result.GlobalContext);
// some code cut here for brevity
throw new DataPortalException(String.Format("DataPortal.Fetch {0} ({1})", Resources.Failed, innerMessage),ex.InnerException, result.ReturnObject);
}
if (proxy.IsServerRemote) ApplicationContext.SetGlobalContext(result.GlobalContext);OnDataPortalInvokeComplete(
new DataPortalEventArgs(dpContext));Notice that on the client side no OnDataPortalInvokeComplete method is called if a DataPortalException occurs. I suggest the following code has the same semantics except a DataPortalInvokeComplete event is raised on the client side regardless of whether or not there was an exception on the server side:
OnDataPortalInvoke(
new DataPortalEventArgs(dpContext)); try{
result = proxy.Fetch(objectType, criteria, dpContext);
}
catch (Server.DataPortalException ex){
result = ex.Result;
throw new DataPortalException(String.Format("DataPortal.Fetch {0} ({1})", Resources.Failed, ex.InnerException.InnerException),ex.InnerException, result.ReturnObject);
}
finally{
if (proxy.IsServerRemote) ApplicationContext.SetGlobalContext(result.GlobalContext);OnDataPortalInvokeComplete(
new DataPortalEventArgs(dpContext));}
Can the same net result be obtained some other way on the client side? Is there a downside to this change other than the behavior changing?
Thanks,
Mike
Yes, that's an interesting point.
I wonder if there shouldn't be a client-side exception event for parity with the server-side behavior?
I suppose you could raise an event on the client side, but we already get a DataPortalException thrown. That is certainly sufficient for my needs. Others may ahve a use for it.
I do suggest changing the client DataPortal code as above or in a way that provides the same effect: a DataPortalInvokeComplete event is raised whether a server-side exception was encountered or not.
Thank you!
Mike
The reason I don’t raise the Complete event is because the
operation didn’t complete due to an exception. I’m not sure it
makes logical sense to raise a Complete event for something that didn’t
complete.
What is the specific thing you are trying to accomplish?
Rocky
From: Wally417
[mailto:cslanet@lhotka.net]
Sent: Friday, January 11, 2008 9:21 PM
To: rocky@lhotka.net
Subject: Re: [CSLA .NET] DataPortalInvokeComplete Event Not Raised After
Exception
I suppose you could raise an event on the client side, but we already get a
DataPortalException thrown. That is certainly sufficient for my needs. Others
may ahve a use for it.
I do suggest changing the client DataPortal code as above or in a way that
provides the same effect: a DataPortalInvokeComplete event is raised whether a
server-side exception was encountered or not.
Thank you!
Mike
Right now I'd like to do some simple UI animation while a DataPortal event is taking place. I can easily imagine other ways in which I might want to use those events, including instrumentation (as in your post here http://forums.lhotka.net/forums/post/2409.aspx) or DataPortal metering. The DataPortalInvoke/DataPortalInvokeComplete events seem to me the natural hooks for this kind of functionality. The alternative that jumps into my mind is to sprinkle DataPortalInvoke/Complete analogs in the business class DataPortal_xxx methods, which I think is not a particularly palatble solution.
You could add a boolean Success flag to DataPortalEventArgs to indicate whether the operation completed successfully or with an exception.
I suppose you may consider making my suggested modifications a breaking change since the behavior of the framework would indeed be different. I suspect this would be a very mild severity breaking change, though. A scan of the forum posts for DataPortalInvoke/Complete/DataPortalEventArgs leads me to think users of these events assume that if a DataPortalInvoke event is raised, a DataPortalInvokeComplete event will follow.
If I use the current framework code and instrument an application to gather DataPortal method timings using the Invoke/Complete events as you suggest in the post noted above, how would I handle the timer in the case of an exception? Would I need to add code to each DataPortalException catch block to signal completion of the method call?
Thanks again!
Mike
If I added a DataPortalException event it would be a
static/Shared event just like the current events, so I imagine you’d call
your timer-end code from both the Complete and Exception events – but there’d
be just two locations, not n locations.
However, your idea of passing a status field (and the exception
itself perhaps) to the Completed event seems quite reasonable as well. I don’t
remember if those events receive any args parameter at the moment, but they’d
need to start doing so to follow this train of thought. That’d be a
breaking change if such a parameter needs to be added (at least in C# - VB 9
now has relaxed delegate invocation that would allow any existing event handler
to work).
Rocky
From: Wally417
[mailto:cslanet@lhotka.net]
Sent: Saturday, January 12, 2008 4:45 PM
To: rocky@lhotka.net
Subject: Re: [CSLA .NET] RE: DataPortalInvokeComplete Event Not Raised
After Exception
Right now I'd like to do some simple UI animation while a DataPortal event
is taking place. I can easily imagine other ways in which I might want to use
those events, including instrumentation (as in your post here http://forums.lhotka.net/forums/post/2409.aspx)
or DataPortal metering. The DataPortalInvoke/DataPortalInvokeComplete events
seem to me the natural hooks for this kind of functionality. The
alternative that jumps into my mind is to sprinkle DataPortalInvoke/Complete
analogs in the business class DataPortal_xxx methods, which I think is not a
particularly palatble solution.
You could add a boolean Success flag to DataPortalEventArgs to indicate
whether the operation completed successfully or with an exception.
I suppose you may consider making my suggested modifications a breaking
change since the behavior of the framework would indeed be different. I suspect
this would be a very mild severity breaking change, though. A scan of the
forum posts for DataPortalInvoke/Complete/DataPortalEventArgs leads me to think
users of these events assume that if a DataPortalInvoke event is raised, a
DataPortalInvokeComplete event will follow.
If I use the current framework code and instrument an application to
gather DataPortal method timings using the Invoke/Complete events as you
suggest in the post noted above, how would I handle the timer in the case of an
exception? Would I need to add code to each DataPortalException catch
block to signal completion of the method call?
Thanks again!
Mike
OnDataPortalInvokeComplete takes a DataPortalEventArgs parameter, so it sounds like a deal!
(OK, I understand it takes more thought than that. There may be very good reason to leave the behavior just as it is.)
Mike
Copyright (c) Marimer LLC