我正在开发一个使用Windows Mobile设备调用Web服务的项目。
要求说明如果服务调用失败,则应提示用户重试。目前,有一个服务代理调用Web服务代理上的所有方法,如果调用失败,则会有一些代码提示用户重试,然后再次调用该调用。它看起来像这样:
public void MyServiceCall(string stringArg, bool boolArg, int intArg)
{
try
{
MyWebService.MyServiceCall(stringArg, boolArg, intArg);
}
catch(SoapException ex)
{
bool retry = //a load of horrid code to prompt the user to retry
if (retry)
{
this.MyServiceCall(stringArg, boolArg, intArg);
}
}
}
catch中的东西在系统上看起来比在该片段中看起来更麻烦,并且CTRL-C CTRL-V模式已被用于在每个服务调用中复制它。我想将这个重复的代码重构为一个方法,但我不确定重试方法调用的最佳方法。我正在考虑让一个委托作为我的新方法的参数,但由于我不知道签名,我不确定如何以通用方式执行此操作。有人可以帮忙吗?感谢。
答案 0 :(得分:7)
我认为你只需要两种方法:
protected void Invoke(Action action) {
try {
action();
} catch {...} // your long boilerplate code
}
protected T Invoke<T>(Func<T> func) {
try {
return func();
} catch {...} // your long boilerplate code
}
然后你可以使用:
public void MyServiceCall(string stringArg, bool boolArg, int intArg)
{
Invoke(() => MyWebService.MyServiceCall(stringArg, boolArg, intArg));
}
同样使用其他版本的方法返回值。如果需要,您还可以让代理人将服务本身作为参数 - 这可能因IDisposable
原因而有用:
protected void Invoke(Action<MyService> action) {
using(MyService svc = new MyService()) {
try {
action(svc);
} catch {...} // your long boilerplate code
}
}
...
public void MyServiceCall(string stringArg, bool boolArg, int intArg)
{
Invoke(svc => svc.MyServiceCall(stringArg, boolArg, intArg));
}
答案 1 :(得分:2)
只需在我的脑海中编写代码......你也可以为Func实现类似的东西来返回值。
public static void ExecuteServiceCall(Action serviceCall) {
while (true) {
try {
serviceCall();
return;
} catch (SoapException ex) {
bool retry = // whaazzaaaaa!?
if (!retry)
// Dont retry, but fail miserably. Or return. Or something.
throw;
}
}
}
public void MyServiceCall(string stringArg, bool boolArg, int intArg) {
ExecuteServiceCall(() => MyWebService.MyServiceCall(stringArg, boolArg, intArg));
}