2016-10-05 17 views
0

私はこれで苦労しています。タスクが別の環境で動作しなくなる

だから私のasp.netアプリケーションでは、このような方法がある:

public CopyResponse thirdStage(CopyRequest request) 
{ 
    CopyCCResponse response = new CopyCCResponse(); 

    Task.Run(() => 
    { 
     performCopying(request); 
    }); 

    return response; 
} 

private void performCopying(CopyCCRequest request) 
{ 
    using (Repository = new myDbContext()) 
    { 
     // do some initial action 
     try 
     { 
     // in general it looks like below 
      foreach(var children in father) 
      { 
       var newChildren = chldren.Copy(); 
       Repository.Childrens.Add(newChildren); 

       foreach (var grandchldren in children.grandchildrens) 
       { 
        var newGrandchildren = grandchldren.Copy(); 
        newGrandchildren.Parent = newChildren; 

        Repository.Grandchildrens.Add(newGrandchildren); 
       } 

       Repository.SaveChanges(); 
      } 
     } 
     catch (Exception ex) 
     { 
      // log that action failed 

      throw ex; 
     } 
    } 
} 

この方法と、(いくつかの類似したがある)他のすべては、何の問題もなく私のローカルコンピュータ上で設計どおりに動作します。

残念ながら、別の環境にこれらのメソッドは失敗:

  • は、データの小さな部分をコピーすると、正常に動作します。しかし、操作するオブジェクトが3000を超えると、メソッドは失敗します。
  • メインアプリケーションは正しく応答しています。
  • ほとんどの操作は正常に実行されます(ほとんどのデータはコピーされ、データベースに保存されます)
  • アプリケーションはキャッチブロックに入りません。失敗したコピーの指示は実行されません。例外はエラーハンドラでは検出されません(BTW、私はデフォルトでアプリケーションが独立タスクの例外をキャッチできないことを知っています。
  • IISワーカープロセスは、コピーが停止した後で300MB以上のプロセッサパワーを消費すると思われます。サーバー上のRAMの半分以上はまだ無料です。
  • 私はWindowsのイベントログを調べましたが、何も見つかりませんでした。

この問題を解決する方法はありますか?

答えて

1

IIS内部から信頼できる「ファイアアンドアフェア」タスクを実行できません。サイトがサービスされていない場合、しばらくするとアプリケーションプールにはAppDomainがシャットダウンします。使用する

つのオプションがあります:あなたがバックグラウンドの仕事をしているIISを伝えるために

HostingEnvironment.QueueBackgroundWorkItem。これにより、サーバーは作業を知ることができ、プロセスを終了する前にシャットダウンを遅延させることができます(最大90秒まで)。

public CopyResponse thirdStage(CopyRequest request) 
{ 
    CopyCCResponse response = new CopyCCResponse(); 

    HostingEnvironment.QueueBackgroundWorkItem(() => 
    { 
     performCopying(request); 
    }); 

    return response; 
} 

別のオプションは、Hangfire.ioようにIISでのバックグラウンド作業を行うために設計されているサードパーティのライブラリを使用することで、この作業を行い、作業まで生きインスタンスを保持しようとIISの内部サ​​ービスを実行します終わらせる。また、IISインスタンスの存続期間に頼る必要がないように、個別のプロセスとして実行するようにHangfireを構成することもできます。別々のプロセスでhangfireを使用して

public CopyResponse thirdStage(CopyRequest request) 
{ 
    CopyCCResponse response = new CopyCCResponse(); 

    BackgroundJob.Enqueue(() => 
    { 
     performCopying(request); 
    }); 

    return response; 
} 

注意、変更する必要はないはずIISインスタンス内から、それを使用して、別のプロセスから実行されてサポートするためにperformCopying(CopyCCRequest request)の少し再設計を行うにはあなたが必要な場合があります。

+0

ありがとうございます。あなたは、 'HostingEnvironment.QueueBackgroundWorkItem'は、できる限りシャットダウンを遅らせると書いています。これは、大きくて長いバックグラウンドプロセスを開始するには依然として信頼できる解決策ではないことを意味します。 –

+0

はい。プロセスがhangfire.ioを使用して90秒以上かかると思う場合は、より良いオプションです。別のサービスとして実行するのが最適ですが、クラスをSerialize可能にするにはコードを変更する必要があります。それをプロセスで実行することもできますが、90秒を超えるとどれくらいの時間がかかりますか分かりません。 91秒、4日、私は分かりません –

関連する問題