473,386 Members | 1,621 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,386 software developers and data experts.

Redo the same method call a second time

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<Adel)
{
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, Bdel)
{
// 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
Oct 28 '07 #1
7 1882
Sure. Just create a wrapper function that just calls the failing function
in a loop. For example:

void Foo()
{
<Do Stuff>
while (!SomeOtherFuction())
{
}
<Do More Stuff>
}

bool SomeOtherFunction()
{
try
{
FunctionThatMayFail()
return true;
} catch (TimeoutException e)
{
return false;
}
}

void FunctionThatMayFail()
{
<Web Service Opps that may fail>
}

Note: That this code can go in to an infinite loop if the web service call
always times out.

--
Andrew Faust
andrew[at]andrewfaust.com
http://www.andrewfaust.com
"Peter Laan" <pl********@yahoo.sewrote in message
news:us**************@TK2MSFTNGP02.phx.gbl...
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<Adel)
{
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, Bdel)
{
// 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

Oct 29 '07 #2

"Andrew Faust" <an****@andrewfaust.comwrote
Sure. Just create a wrapper function that just calls the failing function
in a loop. For example:
The problem is that there are lots of those functions. So I was trying to
come up with a general solution without having to duplicate the redo logic
every time.

Peter
Oct 29 '07 #3
Fair enough. Then we need to pull it out one extra step.

void Foo()
{
<Do Stuff>

RetryableFunction(new MyRetryableFunctionDelgate(FunctionThatMayFail));
RetryableFunction(new
MyRetryableFunctionDelegate(OtherRandomFailableFun ction));

<Do More Stuff>
}

delegate void MyRetryableFunctionDelegate();

void RetryableFunction(MyRetryableFunctionDelegate FunctionToRun)
{
while (!FunctionExecuter(FunctionToRun))
{
}
}

bool FunctionExecuter(MyRetryableFunctionDelegate FunctionToRun)
{
try
{
FunctionToRun()
return true;
} catch (TimeoutException e)
{
return false;
}
}

void FunctionThatMayFail()
{
<Web Service Opps that may fail>
}

void OtherRandomFailableFunction()
{
<Some Code>
}

--
Andrew Faust
andrew[at]andrewfaust.com
http://www.andrewfaust.com
"Peter Laan" <pl********@yahoo.sewrote in message
news:eH**************@TK2MSFTNGP02.phx.gbl...
>
"Andrew Faust" <an****@andrewfaust.comwrote
>Sure. Just create a wrapper function that just calls the failing
function in a loop. For example:

The problem is that there are lots of those functions. So I was trying to
come up with a general solution without having to duplicate the redo
logic every time.

Peter

Oct 30 '07 #4
"Andrew Faust" <an****@andrewfaust.com>
Fair enough. Then we need to pull it out one extra step.
But the methods have different signatures. And I just realised that some
even have return values. I wish we had macros like in C++.
Peter
Oct 31 '07 #5
That being the case I don't have a good method I can whip out off the top of
my head. I have an idea on where you could look, though. When calling methods
via reflection you have to pass in the Method Name as well as an object array
containing the parameters. You can then get back an object result value.

You might be able to create a method that takes a Method name and takes a
parameter array for all the inputs. This method would return an object. Then
that method could call the actual method via reflection. With this in place
calling your methods from the main code would look something like this.

string myValue = ExecuteRetryableMethod("MyMethod", Param1, Param2, Param3,
....) as string;

DataSet ds = ExecuteRetryableMethod("GetDataSet", Param1, Param2) as DataSet;

However, while I think this is an interesting problem and potential solution
from an academic standpoint I wouldn't recommend you actually do this. While
it may get the desired functionality, I think it will be more trouble than
it's worth in the long term. I would think maintaining and debugging this
over the next few years will consume more time and effort than you would gain
in the short term.

--
Andrew Faust
http://www.andrewfaust.com
"Peter Laan" wrote:
"Andrew Faust" <an****@andrewfaust.com>
Fair enough. Then we need to pull it out one extra step.

But the methods have different signatures. And I just realised that some
even have return values. I wish we had macros like in C++.
Peter
Oct 31 '07 #6
"Andrew Faust" <andrew [at] andrewfaust.comwrote
That being the case I don't have a good method I can whip out off the top
of
my head. I have an idea on where you could look, though. When calling
methods
via reflection you have to pass in the Method Name as well as an object
array
containing the parameters. You can then get back an object result value.
Thank you for your replies Andrew! I think I managed to solve this in the
non-type-safe way. I'll heed your advice and stay away from reflection. So
it's either this non-type-safe solution or copying the 'relog' part to all
methods (about 20 - 30). Which one would you consider less horrible?

int _sessionId;
public void Method1()
{
MethodCaller(new object[] { }, new RvDel(Method1Del));
}
public int Method2(int param1)
{
return (int) MethodCaller(new object[] {param1}, new
RvDel(Method2Del));
}
private object Method1Del(object[] a)
{
RvApi.Method1(_sessionId);
return null;
}
private object Method2Del(object[] a)
{
return RvApi.Method2(_sessionId, (int) a[0]);
}
private delegate object RvDel(object[] a);
private object MethodCaller(object[] a, RvDel del)
{
for (int i = 0; i < 2; i++)
{
try
{
return del(a);
}
catch (Exception)
{
if (i < 1) _sessionId = RvApi.Login();
else throw;
}
}
}

Peter
Oct 31 '07 #7
What you ended up with is conceptually what I was trying to get at in my
last post but without the actual need for reflection. How many different
methods are you calling that needs this encapsulation? If it's only a few
methods I'd create a strongly typed wrapper method to do the try catch loop
for each of the methods. You would have to duplicate the loop for each of
the methods, but not for the actual method calls in your main code.

If you have a lot of different methods that need this retry capability then
the mechanism you ended up with would be the way I'd go. However, you may
want to consider putting that functionality out to a separate class. This
way you only have to be exposed to the strongly typed Method1 & Method2
methods when using this code.

--
Andrew Faust
andrew[at]andrewfaust.com
http://www.andrewfaust.com
"Peter Laan" <pl********@yahoo.sewrote in message
news:ui**************@TK2MSFTNGP04.phx.gbl...
"Andrew Faust" <andrew [at] andrewfaust.comwrote
>That being the case I don't have a good method I can whip out off the
top of
my head. I have an idea on where you could look, though. When calling
methods
via reflection you have to pass in the Method Name as well as an object
array
containing the parameters. You can then get back an object result value.

Thank you for your replies Andrew! I think I managed to solve this in the
non-type-safe way. I'll heed your advice and stay away from reflection.
So it's either this non-type-safe solution or copying the 'relog' part to
all methods (about 20 - 30). Which one would you consider less horrible?

int _sessionId;
public void Method1()
{
MethodCaller(new object[] { }, new RvDel(Method1Del));
}
public int Method2(int param1)
{
return (int) MethodCaller(new object[] {param1}, new
RvDel(Method2Del));
}
private object Method1Del(object[] a)
{
RvApi.Method1(_sessionId);
return null;
}
private object Method2Del(object[] a)
{
return RvApi.Method2(_sessionId, (int) a[0]);
}
private delegate object RvDel(object[] a);
private object MethodCaller(object[] a, RvDel del)
{
for (int i = 0; i < 2; i++)
{
try
{
return del(a);
}
catch (Exception)
{
if (i < 1) _sessionId = RvApi.Login();
else throw;
}
}
}

Peter

Nov 1 '07 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

9
by: Kelly Vernon | last post by:
I have a standard ASP page that appends to an xml page. Currently if there is more than one person attempting to append to the same XML file at a time. One user will have the ability to append,...
6
by: lkrubner | last post by:
I'm offering users the ability to type weblog posts into a form and post them. They type the text into a TEXTAREA which is on a form. The form, when submitted, hits a PHP script. Before it is...
14
by: vince | last post by:
Can I add (append) to an xml file that already contains a serialized object, and be able to deserialize to either or both objects from the same file...??? How is this done...?? thanks, vince
5
by: vincent | last post by:
Hi, If i login to the site again (may be in the same pc or different pc), system must allow me in and end my previous session. How do i go about doing this? This is to ensure that an user...
25
by: Daniel P. | last post by:
MS or anyone still claims that C# and VB.NET generate the exact same IL code? http://www.osnews.com/story.php?news_id=5602&page=3
2
by: Christian H | last post by:
Hello, I've tried to find information about how to implement an Undo/Redo pattern. This article describes such a pattern: http://www.codeproject.com/csharp/PcObjectUndo.asp , but is a little bit...
1
by: ABCL | last post by:
Hi All, I am working on the situation where 2 different Process/Application(.net) tries to open file at the same time....Or one process is updating the file and another process tries to access...
1
by: Steven W. Orr | last post by:
Sorry, I had a small description problem. It's corrected below. I have a base class B and a derived class D which inherits from B. I also have a D2 class which inherits from D. D is used as a...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.