andrew4582

AsyncManagerExtensions

Sep 12th, 2011
290
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 4.68 KB | None | 0 0
  1. using System;
  2. using System.Diagnostics;
  3. using System.Diagnostics.CodeAnalysis;
  4. using System.Threading;
  5. using System.Web.Mvc.Async;
  6.  
  7. namespace Core.Web.MVC {
  8.  
  9.     public static class AsyncManagerExtensions {
  10.  
  11.         [SuppressMessage("Microsoft.Design","CA1031:DoNotCatchGeneralExceptionTypes",Justification = "An unhandled exception here will bring down the worker process.")]
  12.         public static void RegisterTask<TResult>(this AsyncManager asyncManager,Func<object,TResult> callBack,object state = null) {
  13.             if(asyncManager == null) {
  14.                 throw new ArgumentNullException("asyncManager");
  15.             }
  16.             if(callBack == null) {
  17.                 throw new ArgumentNullException("callBack");
  18.             }
  19.  
  20.             asyncManager.OutstandingOperations.Increment();
  21.  
  22.             ThreadPool.QueueUserWorkItem((tpstate) => {
  23.                 try {
  24.  
  25.                     TResult result = callBack(tpstate);
  26.  
  27.                     asyncManager.Parameters["result"] = result;
  28.                 }
  29.                 catch(Exception error) {
  30.                     asyncManager.Parameters["error"] = error;
  31.                     Debug.WriteLine("AsyncManagerExtensions.RegisterTask<TResult> error",error);
  32.                 }
  33.                 finally {
  34.                     asyncManager.OutstandingOperations.Decrement();
  35.                 }
  36.             },state);
  37.         }
  38.         [SuppressMessage("Microsoft.Design","CA1031:DoNotCatchGeneralExceptionTypes",Justification = "An unhandled exception here will bring down the worker process.")]
  39.         public static void RegisterTask(this AsyncManager asyncManager,WaitCallback callBack,object state = null) {
  40.  
  41.             if(asyncManager == null) {
  42.                 throw new ArgumentNullException("asyncManager");
  43.             }
  44.             if(callBack == null) {
  45.                 throw new ArgumentNullException("callBack");
  46.             }
  47.  
  48.             asyncManager.OutstandingOperations.Increment();
  49.  
  50.             ThreadPool.QueueUserWorkItem((tpstate) => {
  51.                 try {
  52.  
  53.                     callBack(tpstate);
  54.                 }
  55.                 catch(Exception error) {
  56.                     asyncManager.Parameters["error"] = error;
  57.                     Debug.WriteLine("AsyncManagerExtensions.RegisterTask error",error);
  58.                 }
  59.                 finally {
  60.                     asyncManager.OutstandingOperations.Decrement();
  61.                 }
  62.             },state);
  63.         }
  64.  
  65.         [SuppressMessage("Microsoft.Design","CA1031:DoNotCatchGeneralExceptionTypes",Justification = "An unhandled exception here will bring down the worker process.")]
  66.         public static void RegisterTask(this AsyncManager asyncManager,Func<AsyncCallback,IAsyncResult> beginDelegate,Action<IAsyncResult> endDelegate) {
  67.             if(asyncManager == null) {
  68.                 throw new ArgumentNullException("asyncManager");
  69.             }
  70.             if(beginDelegate == null) {
  71.                 throw new ArgumentNullException("beginDelegate");
  72.             }
  73.             if(endDelegate == null) {
  74.                 throw new ArgumentNullException("endDelegate");
  75.             }
  76.  
  77.             // need to wait to execute the callback until after BeginXxx() has completed
  78.             object delegateExecutingLockObj = new object();
  79.  
  80.             AsyncCallback callback = ar => {
  81.                 lock(delegateExecutingLockObj) { }
  82.                 if(!ar.CompletedSynchronously) {
  83.                     try {
  84.                         asyncManager.Sync(() => endDelegate(ar)); // called on different thread, so have to take application lock
  85.                     }
  86.                     catch {
  87.                         // Need to swallow exceptions, as otherwise unhandled exceptions on a ThreadPool thread
  88.                         // can bring down the entire worker process.
  89.                     }
  90.                     finally {
  91.                         asyncManager.OutstandingOperations.Decrement();
  92.                     }
  93.                 }
  94.             };
  95.  
  96.             IAsyncResult asyncResult;
  97.             asyncManager.OutstandingOperations.Increment();
  98.             try {
  99.                 lock(delegateExecutingLockObj) {
  100.                     asyncResult = beginDelegate(callback);
  101.                 }
  102.             }
  103.             catch {
  104.                 asyncManager.OutstandingOperations.Decrement();
  105.                 throw;
  106.             }
  107.  
  108.             if(asyncResult.CompletedSynchronously) {
  109.                 try {
  110.                     endDelegate(asyncResult); // call on same thread
  111.                 }
  112.                 finally {
  113.                     asyncManager.OutstandingOperations.Decrement();
  114.                 }
  115.             }
  116.         }
  117.  
  118.     }
  119. }
Advertisement
Add Comment
Please, Sign In to add comment