委托签名/通用代表?

Cha*_*lie 3 .net c#

我正在开发一个使用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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

catch中的东西在系统上看起来比在该片段中看起来更麻烦,并且CTRL-C CTRL-V模式已被用于在每个服务调用中复制它.我想将这个重复的代码重构为一个方法,但我不确定重试方法调用的最佳方法.我正在考虑让一个委托作为我的新方法的参数,但由于我不知道签名,我不确定如何以通用方式执行此操作.有人可以帮忙吗?谢谢.

Mar*_*ell 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
}
Run Code Online (Sandbox Code Playgroud)

然后你可以使用:

public void MyServiceCall(string stringArg, bool boolArg, int intArg)
{
    Invoke(() => MyWebService.MyServiceCall(stringArg, boolArg, intArg));
}
Run Code Online (Sandbox Code Playgroud)

并且同样使用其他版本的方法返回值.如果需要,您还可以让代理人将服务本身作为参数 - 这可能是有用的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));
}
Run Code Online (Sandbox Code Playgroud)