| File: System\ServiceModel\Channels\CloseCollectionAsyncResult.cs | Web Access |
| Project: src\src\System.ServiceModel.Primitives\src\System.ServiceModel.Primitives.csproj (System.ServiceModel.Primitives) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System.Collections.Generic; using System.Runtime; using System.Threading; namespace System.ServiceModel { internal class CloseCollectionAsyncResult : AsyncResult { private bool _completedSynchronously; private Exception _exception; private static AsyncCallback s_nestedCallback = Fx.ThunkCallback(new AsyncCallback(Callback)); private int _count; public CloseCollectionAsyncResult(TimeSpan timeout, AsyncCallback otherCallback, object state, IList<ICommunicationObject> collection) : base(otherCallback, state) { TimeoutHelper timeoutHelper = new TimeoutHelper(timeout); _completedSynchronously = true; _count = collection.Count; if (_count == 0) { Complete(true); return; } for (int index = 0; index < collection.Count; index++) { CallbackState callbackState = new CallbackState(this, collection[index]); IAsyncResult result; try { result = collection[index].BeginClose(timeoutHelper.RemainingTime(), s_nestedCallback, callbackState); } catch (Exception e) { if (Fx.IsFatal(e)) { throw; } Decrement(true, e); collection[index].Abort(); continue; } if (result.CompletedSynchronously) { CompleteClose(collection[index], result); } } } private void CompleteClose(ICommunicationObject communicationObject, IAsyncResult result) { Exception closeException = null; try { communicationObject.EndClose(result); } catch (Exception e) { if (Fx.IsFatal(e)) { throw; } closeException = e; communicationObject.Abort(); } Decrement(result.CompletedSynchronously, closeException); } private static void Callback(IAsyncResult result) { if (result.CompletedSynchronously) { return; } CallbackState callbackState = (CallbackState)result.AsyncState; callbackState.Result.CompleteClose(callbackState.Instance, result); } private void Decrement(bool completedSynchronously) { if (completedSynchronously == false) { _completedSynchronously = false; } if (Interlocked.Decrement(ref _count) == 0) { if (_exception != null) { Complete(_completedSynchronously, _exception); } else { Complete(_completedSynchronously); } } } private void Decrement(bool completedSynchronously, Exception exception) { _exception = exception; Decrement(completedSynchronously); } public static void End(IAsyncResult result) { AsyncResult.End<CloseCollectionAsyncResult>(result); } internal class CallbackState { private CloseCollectionAsyncResult _result; public CallbackState(CloseCollectionAsyncResult result, ICommunicationObject instance) { _result = result; Instance = instance; } public ICommunicationObject Instance { get; } public CloseCollectionAsyncResult Result { get { return _result; } } } } }