protected IAsyncResult BeginSendHelper(IPeerNeighbor neighbor, TimeSpan timeout, Message message, FloodAsyncResult fresult)
        {
            IAsyncResult result = null;
            IAsyncResult result2;
            bool         flag = false;

            try
            {
                UtilityExtension.OnMessageSent(neighbor);
                result = neighbor.BeginSend(message, timeout, Fx.ThunkCallback(new AsyncCallback(fresult.OnSendComplete)), message);
                fresult.AddResult(result, neighbor);
                if (result.CompletedSynchronously)
                {
                    neighbor.EndSend(result);
                    UtilityExtension.OnEndSend(neighbor, fresult);
                }
                result2 = result;
            }
            catch (Exception exception)
            {
                if (Fx.IsFatal(exception))
                {
                    flag = true;
                    throw;
                }
                if (PeerFlooderBase <TFloodContract, TLinkContract> .CloseNeighborIfKnownException(this.neighborManager, exception, neighbor) != null)
                {
                    fresult.MarkEnd(false);
                    throw;
                }
                System.ServiceModel.DiagnosticUtility.ExceptionUtility.TraceHandledException(exception, TraceEventType.Information);
                result2 = null;
            }
            finally
            {
                if (((result == null) || result.CompletedSynchronously) && !flag)
                {
                    message.Close();
                }
            }
            return(result2);
        }
Beispiel #2
0
        protected IAsyncResult BeginSendHelper(IPeerNeighbor neighbor, TimeSpan timeout, Message message, FloodAsyncResult fresult)
        {
            IAsyncResult result = null;
            bool         fatal  = false;

            try
            {
                UtilityExtension.OnMessageSent(neighbor);
                result = neighbor.BeginSend(message, timeout, Fx.ThunkCallback(new AsyncCallback(fresult.OnSendComplete)), message);
                fresult.AddResult(result, neighbor);
                if (result.CompletedSynchronously)
                {
                    neighbor.EndSend(result);
                    UtilityExtension.OnEndSend(neighbor, fresult);
                }
                return(result);
            }
            catch (Exception e)
            {
                if (Fx.IsFatal(e))
                {
                    fatal = true;
                    throw;
                }
                if (null != CloseNeighborIfKnownException(neighborManager, e, neighbor))
                {
                    fresult.MarkEnd(false);
                    throw;
                }

                DiagnosticUtility.TraceHandledException(e, TraceEventType.Information);
                return(null);
            }
            finally
            {
                if ((result == null || result.CompletedSynchronously) && !fatal)
                {
                    message.Close();
                }
            }
        }
Beispiel #3
0
        //this is the callback routine for async completion on channel BeginSend() operations.
        //if we are done, simply return. This can happen if user called sync EndX.
        //if the flooder is still processing BeginSend(), then we probably cant complete. In this case, add the result to pending and return
        //main thread will flush the pending completions in MarkEnd().
        //otherwise, call EndX on the result and remove it from results.
        //if this is the last invoke, signal user using base.Complete AND isCompleted=true
        internal void OnSendComplete(IAsyncResult result)
        {
            bool          callComplete = false;
            IPeerNeighbor neighbor     = null;
            bool          fatal        = false;

            if (isCompleted)
            {
                return;
            }
            Message message = (Message)result.AsyncState;

            //wait until flooder had a chance to call all outgoing channels and give us Async results.
            lock (ThisLock)
            {
                if (isCompleted)
                {
                    return;
                }

                if (!this.results.TryGetValue(result, out neighbor))
                {
                    if (!doneAdding)
                    {
                        this.pending.Add(result);
                    }
                    else
                    {
                        throw Fx.AssertAndThrow("IAsyncResult is un-accounted for.");
                    }
                    return;
                }
                this.results.Remove(result);

                try
                {
                    //try doing this only if the async result is marked !CompletedSynchronously.
                    if (!result.CompletedSynchronously)
                    {
                        neighbor.EndSend(result);
                        offNode = true;
                        UtilityExtension.OnEndSend(neighbor, this);
                    }
                }
                catch (Exception e)
                {
                    if (Fx.IsFatal(e))
                    {
                        fatal = true;
                        throw;
                    }

                    Exception temp = PeerFlooder.CloseNeighborIfKnownException(pnm, e, neighbor);
                    //we want to return the very first exception to the user.
                    if (temp != null && this.doneAdding && !this.shouldCallComplete)
                    {
                        throw;
                    }
                    if (this.exception == null)
                    {
                        this.exception = temp;
                    }
                    DiagnosticUtility.TraceHandledException(e, TraceEventType.Information);
                }
                finally
                {
                    if (message != null && !result.CompletedSynchronously && !fatal)
                    {
                        message.Close();
                    }
                }
                //dont want to call Complete from the lock.
                //we just decide if this thread should call complete and call outside the lock.
                if (this.results.Count == 0 && this.doneAdding && this.shouldCallComplete)
                {
                    this.isCompleted = true;
                    callComplete     = true;
                }
            }
            //if we are done with callbacks and beginx calls,
            if (callComplete && this.shouldCallComplete)
            {
                CompleteOp(false);
            }
        }
Beispiel #4
0
        internal void OnSendComplete(IAsyncResult result)
        {
            bool          flag     = false;
            IPeerNeighbor neighbor = null;
            bool          flag2    = false;

            if (!this.isCompleted)
            {
                Message asyncState = (Message)result.AsyncState;
                lock (this.ThisLock)
                {
                    if (this.isCompleted)
                    {
                        return;
                    }
                    if (!this.results.TryGetValue(result, out neighbor))
                    {
                        if (this.doneAdding)
                        {
                            throw Fx.AssertAndThrow("IAsyncResult is un-accounted for.");
                        }
                        this.pending.Add(result);
                        return;
                    }
                    this.results.Remove(result);
                    try
                    {
                        if (!result.CompletedSynchronously)
                        {
                            neighbor.EndSend(result);
                            this.offNode = true;
                            UtilityExtension.OnEndSend(neighbor, this);
                        }
                    }
                    catch (Exception exception)
                    {
                        if (Fx.IsFatal(exception))
                        {
                            flag2 = true;
                            throw;
                        }
                        Exception exception2 = PeerFlooderBase <Message, UtilityInfo> .CloseNeighborIfKnownException(this.pnm, exception, neighbor);

                        if (((exception2 != null) && this.doneAdding) && !this.shouldCallComplete)
                        {
                            throw;
                        }
                        if (this.exception == null)
                        {
                            this.exception = exception2;
                        }
                        DiagnosticUtility.ExceptionUtility.TraceHandledException(exception, TraceEventType.Information);
                    }
                    finally
                    {
                        if (((asyncState != null) && !result.CompletedSynchronously) && !flag2)
                        {
                            asyncState.Close();
                        }
                    }
                    if (((this.results.Count == 0) && this.doneAdding) && this.shouldCallComplete)
                    {
                        this.isCompleted = true;
                        flag             = true;
                    }
                }
                if (flag && this.shouldCallComplete)
                {
                    this.CompleteOp(false);
                }
            }
        }