Recommendations for executing .NET HttpWebRequests in parallel in ASP.NET

后端 未结 4 1152
失恋的感觉
失恋的感觉 2021-01-13 04:37

I have an ASP.NET MVC web application that makes REST style web service calls to other servers. I have a scenario where I am making two HttpWebRequest calls to two separate

4条回答
  •  醉话见心
    2021-01-13 04:50

    One of the answers to Multithreading WebRequests, a good and stable approach? : CSharp uses a ManualResetEvent event = new ManualResetEvent(), a reference counter equaling the number of in flight requests and Interlocked.Decrement to control the event.Set(). The main thread then waits by calling event.WaitOne().

    However, WaitHandles - Auto/ManualResetEvent and Mutex mentions that ManualResetEvent "can be significantly slower than using the various Monitor methods" like Wait, Pulse and PulseAll.

    I ended up basing my code off of this Noah Blumenthal blog post: Run generic tasks async (fluent-ly). I did make two changes: implement IDisposable and call .Close() on the ManualResetEvent and switch from using a lock() to Interlocked .Increment() and .Decrement().

    public class AsyncQueueManager : IDisposable {
        private readonly ManualResetEvent waitHandle = new ManualResetEvent(true);
        private int count = 0;
    
        public AsyncQueueManager Queue(Action action) {
            Interlocked.Increment(ref count);
            waitHandle.Reset();
            Action actionWrapper = CreateActionWrapper(action);
            WaitCallback waitCallback = new WaitCallback(actionWrapper);
            ThreadPool.QueueUserWorkItem(waitCallback);
            return this;
        }
    
        private Action CreateActionWrapper(Action action) {
            Action actionWrapper = (object state) =>
            {
                try {
                    action(state);
                } catch (Exception ex) {
                    // log
                } finally {
                    if (Interlocked.Decrement(ref count) == 0) {
                        waitHandle.Set();
                    }
                }
            };
            return actionWrapper;
        }
    
        public void Wait() {
            waitHandle.WaitOne();
        }
        public void Wait(TimeSpan timeout) {
            waitHandle.WaitOne(timeout);
        }
    
        public void Dispose() {
            waitHandle.Close();
        }
    }
    
        

    提交回复
    热议问题