2009-06-26 11 views
0

ウェブアプリケーションでxml Webサービスを使用しています。私は、最初の試行が失敗した場合に再リクエストという考えを思いつきました。ループを防ぐために、私は同時リクエストを2に制限したいと思っています。私が下で行ったことが大丈夫で、私が期待している通りに動いたら、意見を出したいと思います。最初のリクエストが失敗した場合は、リクエストを再試行してください。

public class ScEngine 
{ 
    private int _attemptcount = 0; 
    public int attemptcount 
    { 
     get 
     { 
      return _attemptcount; 
     } 
     set 
     { 
      _attemptcount = value; 
     } 
    } 

    public DataSet GetStat(string q, string job) 
    { 

     try 
     { 
      //snip.... 
      attemptcount += attemptcount; 
      return ds; 

     } 
     catch 
     { 
      if (attemptcount>=2) 
      { 
      return null; 
      } 
      else 
      { 
       return GetStat(q, job); 
      } 

     } 

    } 
} 
+1

このアプローチでは非常に注意してください。それはうまく "巣立つ"わけではありません。あきらめる前に5回操作を再試行する低レベルメソッドがあるとします。その呼び出し元は、あきらめる前に5回再試行します。そしてその呼び出し元は5回再試行して、あきらめる。突然、あなたはあきらめる前に実際に再試行しています。実際の状況では、2秒以内にエラーコードを返すべきコードが、アプリケーションをハングアップしているような、1週間以上にわたって深くネストされた再試行でそこに座っていました。通常は失敗して再試行するかどうかをユーザーに決定させる方がよいでしょう。 –

答えて

1
public class ScEngine 
{ 
    public DataSet GetStat(string q, string job) 
    { 
     int attemptCount; 
     while(attemptCount < 2) 
     { 
      try 
      { 
       attemptCount++; 
       var ds = ...//web service call 
       return ds; 
      } 
      catch {} 
     } 
     //log the error 
     return null; 
    } 
} 
+1

これは例外を破棄し、それらをログに記録しません。例外が「タイムアウト」やそれに類するものではないことが判明した場合は非常に悪いことです。 –

+0

もちろん、キャッチにもログを追加することができます。再試行回数を記録することもできます。 – RedFilter

1

試行回数を増やすのを忘れました。さらに、2回目の実行でエラーが発生した場合、それは捕捉されません(したがって、未処理の例外になります)。

+0

また、試行回数> = 2でなければ、それは3回試行されます... – RedFilter

+0

実際には、2回目の実行時のエラーは、GetStatを呼び出しているために2回目のtry/catchで実行されるため、メソッドを再度実行します。 –

0

私は再試行するために再発しません。また、私はすべての例外をキャッチして無視しません。私は、どの例外が再試行されるべきかを示す例外を知り、それらをキャッチします。あなたのコードが立つので、重大なエラーは無視されます。

0

あなたはこのように解決したくありません。サーバーに負荷をかけてタイムアウトを増やすだけです。

Webサービスタイムアウトを増やすことができますvia httpRuntime。 Webサービスは通常、1回の呼び出しで多くのデータを返します。クライアントがクライアント側で待機する時間を増やすことを忘れないでください。

0

ここでは、再帰を使用しないが、同じ結果を達成するバージョンがあります。それには遅延も含まれているため、サーバーに問題が発生した場合に回復する時間を与えることができます。

/// <summary> 
    /// The maximum amount of attempts to use before giving up on an update, delete or create 
    /// </summary> 
    private const int MAX_ATTEMPTS = 2; 

    /// <summary> 
    /// Attempts to execute the specified delegate with the specified arguments. 
    /// </summary> 
    /// <param name="operation">The operation to attempt.</param> 
    /// <param name="arguments">The arguments to provide to the operation.</param> 
    /// <returns>The result of the operation if there are any.</returns> 
    public static object attemptOperation(Delegate operation, params object[] arguments) 
    { 
     //attempt the operation using the default max attempts 
     return attemptOperation(MAX_ATTEMPTS, operation, arguments); 
    } 

    /// <summary> 
    /// Use for creating a random delay between retry attempts. 
    /// </summary> 
    private static Random random = new Random(); 

    /// <summary> 
    /// Attempts to execute the specified delegate with the specified arguments. 
    /// </summary> 
    /// <param name="operation">The operation to attempt.</param> 
    /// <param name="arguments">The arguments to provide to the operation.</param> 
    /// <param name="maxAttempts">The number of times to attempt the operation before giving up.</param> 
    /// <returns>The result of the operation if there are any.</returns> 
    public static object attemptOperation(int maxAttempts, Delegate operation, params object [] arguments) 
    { 
     //set our initial attempt count 
     int attemptCount = 1; 

     //set the default result 
     object result = null; 

     //we've not succeeded yet 
     bool success = false; 

     //keep trying until we get a result 
     while (success == false) 
     { 
      try 
      { 
       //attempt the operation and get the result 
       result = operation.DynamicInvoke(arguments); 
       //we succeeded if there wasn't an exception 
       success = true; 
      } 
      catch 
      { 
       //if we've got to the max attempts and still have an error, give up an rethrow it 
       if (attemptCount++ == maxAttempts) 
       { 
        //propogate the exception 
        throw; 
       } 
       else 
       { 
        //create a random delay in milliseconds 
        int randomDelayMilliseconds = random.Next(1000, 5000); 
        //sleep for the specified amount of milliseconds 
        System.Threading.Thread.Sleep(randomDelayMilliseconds); 
       } 
      } 
     } 

     //return the result 
     return result; 
    } 
関連する問題