代码之家  ›  专栏  ›  技术社区  ›  Charlie Gevious

委托签名/一般委托?

  •  3
  • Charlie Gevious  · 技术社区  · 15 年前

    我正在做一个使用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模式来复制它。我想将这个重复的代码重构成一个方法,但我不确定重试方法调用的最佳方法。我本来想让一个委托作为我新方法的一个论点,但是由于我不知道签名,所以我不确定如何用一般的方式来做这件事。有人能帮忙吗?谢谢。

    2 回复  |  直到 15 年前
        1
  •  7
  •   Marc Gravell    15 年前

    我认为你只需要两种方法:

    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));
    }
    
        2
  •  2
  •   sisve    15 年前

    只是在我脑子里编代码…您还可以实现类似的功能,以便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));
    }