P
Peter Laan
Is there a simple way to encapsulate the functionality to redo a method call
a second time in case a specific exception is thrown? We are sending
commands to an external system and if the sessionId times out we want to
relogin to get a new sessionId and then call the same method a second time.
The method calls are actually calls to our own web service who in turn sends
the command to the external system.
My first solution using .net 1.1 uses a delegate with object[] as parameter.
RvApi is the webservice referens.
class RV
{
int _sessionId;
public void MuteAll(int confId)
{
RvCall(new object[] {confId}, new RvDel(MuteAllDel));
}
private void MuteAllDel(object[] a)
{
RvApi.MuteAll(_sessionId, (int) a[0]);
}
private delegate void RvDel(object[] a);
private void RvCall(object[] a, RvDel del)
{
for (int i = 0; i < 2; i++)
{
try
{
del(a);
return;
}
catch (Exception)
{
_sessionId = RvApi.Login();
}
}
}
}
I can't say I like this solution. The main drawback being the lack of type
safety.
Using lambda functions in 3.5 I came up with this variant.
class RV
{
int _sessionId;
public void DialOut(int confId, string phone)
{
RvCall2<int, string>(confId, phone, (x, y) =>
RvApi.DialOut(_sessionId, x, y));
}
public void MuteAll(int confId)
{
RvCall1<int>(confId, x => RvApi.MuteAll(_sessionId, x));
}
private delegate void RvDel1<A>(A a);
private delegate void RvDel2<A, B>(A a, B b);
private void RvCall1<A>(A a, RvDel1<A> del)
{
for (int i = 0; i < 2; i++)
{
try
{
del(a);
return;
}
catch (Exception)
{
// Relog to get new sessionId
}
}
}
private void RvCall2<A, B>(A a, B b, RvDel2<A, B> del)
{
// same crap to handle relogins
del(a, b);
}
}
Now I get type safety, but have to create a new delegate and RvCall-function
each time a method needs more parameters.
I suppose I could rewrite all web service methods to only use single
parameter, but then I would have to create a class for each method. Another
idea would be to use reflection. I don't think there will be any performance
problems, so it might be ok. Are there any better solutions? If not, which
one would you prefer?
Peter
a second time in case a specific exception is thrown? We are sending
commands to an external system and if the sessionId times out we want to
relogin to get a new sessionId and then call the same method a second time.
The method calls are actually calls to our own web service who in turn sends
the command to the external system.
My first solution using .net 1.1 uses a delegate with object[] as parameter.
RvApi is the webservice referens.
class RV
{
int _sessionId;
public void MuteAll(int confId)
{
RvCall(new object[] {confId}, new RvDel(MuteAllDel));
}
private void MuteAllDel(object[] a)
{
RvApi.MuteAll(_sessionId, (int) a[0]);
}
private delegate void RvDel(object[] a);
private void RvCall(object[] a, RvDel del)
{
for (int i = 0; i < 2; i++)
{
try
{
del(a);
return;
}
catch (Exception)
{
_sessionId = RvApi.Login();
}
}
}
}
I can't say I like this solution. The main drawback being the lack of type
safety.
Using lambda functions in 3.5 I came up with this variant.
class RV
{
int _sessionId;
public void DialOut(int confId, string phone)
{
RvCall2<int, string>(confId, phone, (x, y) =>
RvApi.DialOut(_sessionId, x, y));
}
public void MuteAll(int confId)
{
RvCall1<int>(confId, x => RvApi.MuteAll(_sessionId, x));
}
private delegate void RvDel1<A>(A a);
private delegate void RvDel2<A, B>(A a, B b);
private void RvCall1<A>(A a, RvDel1<A> del)
{
for (int i = 0; i < 2; i++)
{
try
{
del(a);
return;
}
catch (Exception)
{
// Relog to get new sessionId
}
}
}
private void RvCall2<A, B>(A a, B b, RvDel2<A, B> del)
{
// same crap to handle relogins
del(a, b);
}
}
Now I get type safety, but have to create a new delegate and RvCall-function
each time a method needs more parameters.
I suppose I could rewrite all web service methods to only use single
parameter, but then I would have to create a class for each method. Another
idea would be to use reflection. I don't think there will be any performance
problems, so it might be ok. Are there any better solutions? If not, which
one would you prefer?
Peter