2017-02-13 15 views
0

私はMVC APIコントローラを持っています。 このコントローラの1つの方法が重要です。 これは、他のすべてのAPIメソッドがこのメソッドを完了するのを待つ必要があることを意味します。APIメソッドはクリティカルメソッドが完了するまで待つ必要があります

私の基本的な考えは、コンストラクタでスレッドをブロックすることです。 これはとてもスマートなのかどうか分かりませんが? (すべてのコントローラ共通)の基底クラスで

私は方法BlockOtherRequestsBeforeExecuteを追加します。

public class TestApi : Controller 
{ 
    private static bool wait = false; 
    public TestApi() 
    { 
     // wait if critical method is working. 
     while (wait) 
     { 
      System.Threading.Thread.Sleep(100); 
     } 
    } 

    [HttpPost] 
    public void PostCriticalMethod() 
    { 
     try 
     { 
      wait = true; 
      // do critical work 
     } 
     finally 
     { 
      wait = false; 
     } 
    } 
    // Many non critical API methods... 
} 

対処方法2:

public class TestApi : Controller 
    { 
     private static bool wait = false; 
     private static AutoResetEvent waitHandle = new AutoResetEvent(false); 
     public TestApi() 
     { 
      // wait if critical method is working. 
      if (wait) waitHandle.WaitOne(); 
     } 

     [HttpPost] 
     public void PostCriticalMethod() 
     { 
      try 
      { 
      wait = true; 
      // do critical work 
      } 
      finally { 
      waitHandle.Set(); 
      wait = false; 
      } 
     }   
     // Many non critical API methods... 
    } 
+5

これはAPIで必要な場合は、私の意見では、デザインの再考が必要になります。アピスはこのように動くはずがありません。なぜこれが必要ですか?あなたの解決策の代わりにあなたの挑戦を伝えたら、おそらく私たちはより良く助けることができます。 –

+0

データベースを復元するタスクがAPIを持っています。他のAPIメソッドは、データベースが復元されるまで待つ必要があります。 – Raskolnikov

+0

このアプローチの欠点は、最初のAPIリクエストが作成されたとき(そのコントローラに対するリクエスト)にDBの復元が開始され、遅すぎると思います。 APIを要求している最初のクライアントは、確実に(他の呼び出し元も)ブロックされます(リストア処理が行われている限り)。より良いアプローチは、WEB起動時にこの「復元タスク」を実行することです。 – tomassino

答えて

0

私のソリューションは、(これは、非同期バージョンですが、非非同期でさえも簡単です)

私は、必要な場合に安全な方法でメソッドを呼び出すことができます:

await BlockOtherRequestsBeforeExecute(async() => await RestoreDatabase()); 

重要な部分はsemaphoreInitは、すべての重要な場所で使用しなければならないということです。 これは基本クラスのコンストラクタで行うことができ、重要なアクションが終了しない限りすべてのAPIはブロックされます。

関連する問題