< Summary - CoreWCF Coverage — PR #1766

Information
Class: CoreWCF.Channels.CommunicationObject
Assembly: CoreWCF.Primitives
File(s): /home/runner/work/CoreWCF/CoreWCF/src/CoreWCF.Primitives/src/CoreWCF/Channels/CommunicationObject.cs
Line coverage
55%
Covered lines: 145
Uncovered lines: 116
Coverable lines: 261
Total lines: 826
Line coverage: 55.5%
Branch coverage
47%
Covered branches: 66
Total branches: 140
Branch coverage: 47.1%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Cyclomatic complexity NPath complexity Sequence coverage
.ctor()100%11100%
.ctor(...)100%11100%
Abort()75%8885.71%
CloseAsync()100%11100%
CloseAsync()76.47%171783.33%
OpenAsync()100%11100%
OpenAsync()66.66%6688.88%
Fault(...)0%220%
AddPendingException(...)0%220%
GetPendingException()0%220%
Fault()83.33%6688.88%
ThrowIfClosed()57.14%7750%
GetCommunicationObjectType()100%110%
OnClosed()50%6668.75%
OnClosing()50%6660%
OnFaulted()50%6664.28%
OnOpened()62.5%8886.66%
OnOpening()50%4460%
ThrowIfFaulted()71.42%7760%
ThrowIfAborted()0%440%
CreateNotOpenException()100%110%
CreateBaseClassMethodNotCalledException(...)100%110%
CreateImmutableException()100%110%
CreateClosedException()0%220%
CreateFaultedException()100%110%
CreateAbortedException()100%110%
ThrowIfDisposed()42.85%7742.85%
ThrowIfClosedOrOpened()28.57%7737.5%
ThrowIfDisposedOrImmutable()14.28%7733.33%
ThrowIfDisposedOrNotOpen()14.28%7733.33%
ThrowIfNotOpened()50%4466.66%
ThrowIfClosedOrNotOpen()28.57%7737.5%
ThrowPending()50%4450%
.ctor(...)100%110%
AddException(...)0%220%
GetException()0%220%

File(s)

/home/runner/work/CoreWCF/CoreWCF/src/CoreWCF.Primitives/src/CoreWCF/Channels/CommunicationObject.cs

#LineLine coverage
 1// Licensed to the .NET Foundation under one or more agreements.
 2// The .NET Foundation licenses this file to you under the MIT license.
 3
 4using System;
 5using System.Collections.Generic;
 6using System.Threading;
 7using System.Threading.Tasks;
 8using CoreWCF.Diagnostics;
 9using CoreWCF.Runtime;
 10
 11namespace CoreWCF.Channels
 12{
 13    // TODO: Go through and verify all the internal methods to see if they are needed/used
 14    public abstract class CommunicationObject : ICommunicationObject
 15    {
 16        private bool _closeCalled;
 17        private ExceptionQueue _exceptionQueue;
 18        private bool _onClosingCalled;
 19        private bool _onClosedCalled;
 20        private bool _onOpeningCalled;
 21        private bool _onOpenedCalled;
 22        private bool _raisedClosed;
 23        private bool _raisedClosing;
 24        private bool _raisedFaulted;
 25
 1372626        protected CommunicationObject() : this(new object()) { }
 27
 686328        protected CommunicationObject(object mutex)
 29        {
 686330            ThisLock = mutex;
 686331            EventSender = this;
 686332            State = CommunicationState.Created;
 686333        }
 34
 739335        internal bool Aborted { get; private set; }
 36
 759837        internal object EventSender { get; set; }
 38
 39        protected bool IsDisposed
 40        {
 041            get { return State == CommunicationState.Closed; }
 42        }
 43
 8649044        public CommunicationState State { get; private set; }
 45
 5177946        protected object ThisLock { get; }
 47
 48        protected abstract TimeSpan DefaultCloseTimeout { get; }
 49        protected abstract TimeSpan DefaultOpenTimeout { get; }
 50
 51        internal TimeSpan InternalCloseTimeout
 52        {
 053            get { return DefaultCloseTimeout; }
 54        }
 55
 56        internal TimeSpan InternalOpenTimeout
 57        {
 51658            get { return DefaultOpenTimeout; }
 59        }
 60
 61        public event EventHandler Closed;
 62        public event EventHandler Closing;
 63        public event EventHandler Faulted;
 64        public event EventHandler Opened;
 65        public event EventHandler Opening;
 66
 67        public void Abort()
 68        {
 58569            lock (ThisLock)
 70            {
 58571                if (Aborted || State == CommunicationState.Closed)
 72                {
 173                    return;
 74                }
 75
 58476                Aborted = true;
 58477                State = CommunicationState.Closing;
 58478            }
 79
 80            //if (DiagnosticUtility.ShouldTraceInformation)
 81            //{
 82            //    TraceUtility.TraceEvent(TraceEventType.Information, TraceCode.CommunicationObjectAborted, SR.Format(SR
 83            //}
 84
 85            //bool throwing = true;
 86
 87            //try
 88            //{
 58489            OnClosing();
 58490            if (!_onClosingCalled)
 91            {
 092                throw TraceUtility.ThrowHelperError(CreateBaseClassMethodNotCalledException("OnClosing"), Guid.Empty, th
 93            }
 94
 58495            OnAbort();
 96
 58497            OnClosed();
 58498            if (!_onClosedCalled)
 99            {
 0100                throw TraceUtility.ThrowHelperError(CreateBaseClassMethodNotCalledException("OnClosed"), Guid.Empty, thi
 101            }
 102
 103            //throwing = false;
 104            //}
 105            //finally
 106            //{
 107            //    if (throwing)
 108            //    {
 109            //        if (DiagnosticUtility.ShouldTraceWarning)
 110            //            TraceUtility.TraceEvent(TraceEventType.Warning, TraceCode.CommunicationObjectAbortFailed, SR.F
 111            //    }
 112            //}
 585113        }
 114
 115        public Task CloseAsync()
 116        {
 2934117            var helper = new TimeoutHelper(DefaultCloseTimeout);
 2934118            return CloseAsync(helper.GetCancellationToken());
 119        }
 120
 121        public async Task CloseAsync(CancellationToken token)
 122        {
 3091123            token.ThrowIfCancellationRequested();
 124
 125            //using (DiagnosticUtility.ShouldUseActivity && this.TraceOpenAndClose ? this.CreateCloseActivity() : null)
 126            //{
 127
 128            CommunicationState originalState;
 3091129            lock (ThisLock)
 130            {
 3091131                originalState = State;
 3091132                if (originalState != CommunicationState.Closed)
 133                {
 3021134                    State = CommunicationState.Closing;
 135                }
 136
 3091137                _closeCalled = true;
 3091138            }
 139
 140            switch (originalState)
 141            {
 142                case CommunicationState.Created:
 143                case CommunicationState.Opening:
 144                case CommunicationState.Faulted:
 518145                    Abort();
 518146                    if (originalState == CommunicationState.Faulted)
 147                    {
 0148                        throw TraceUtility.ThrowHelperError(CreateFaultedException(), Guid.Empty, this);
 149                    }
 150                    break;
 151
 152                case CommunicationState.Opened:
 153                    {
 2499154                        bool throwing = true;
 155                        try
 156                        {
 157                            //TimeoutHelper actualTimeout = new TimeoutHelper(timeout);
 158
 2499159                            OnClosing();
 2499160                            if (!_onClosingCalled)
 161                            {
 0162                                throw TraceUtility.ThrowHelperError(CreateBaseClassMethodNotCalledException("OnClosing")
 163                            }
 164
 2499165                            await OnCloseAsync(token);
 166
 2494167                            OnClosed();
 2494168                            if (!_onClosedCalled)
 169                            {
 0170                                throw TraceUtility.ThrowHelperError(CreateBaseClassMethodNotCalledException("OnClosed"),
 171                            }
 172
 2494173                            throwing = false;
 2494174                        }
 175                        finally
 176                        {
 2499177                            if (throwing)
 178                            {
 179                                //if (DiagnosticUtility.ShouldTraceWarning)
 180                                //{
 181                                //    TraceUtility.TraceEvent(TraceEventType.Warning, TraceCode.CommunicationObjectClose
 182                                //}
 183
 5184                                Abort();
 185                            }
 186                        }
 187                        break;
 188                    }
 189
 190                case CommunicationState.Closing:
 191                case CommunicationState.Closed:
 192                    break;
 193
 194                default:
 0195                    throw Fx.AssertAndThrow("CommunicationObject.BeginClose: Unknown CommunicationState");
 196            }
 197            //}
 198
 3086199        }
 200
 201        public System.Threading.Tasks.Task OpenAsync()
 202        {
 3316203            CancellationToken token = new TimeoutHelper(DefaultOpenTimeout).GetCancellationToken();
 3316204            return OpenAsync(token);
 205        }
 206
 207        public async Task OpenAsync(CancellationToken token)
 208        {
 6224209            token.ThrowIfCancellationRequested();
 210
 211            //using (ServiceModelActivity activity = DiagnosticUtility.ShouldUseActivity && this.TraceOpenAndClose ? Ser
 212            //{
 213            //if (DiagnosticUtility.ShouldUseActivity)
 214            //{
 215            //    ServiceModelActivity.Start(activity, this.OpenActivityName, this.OpenActivityType);
 216            //}
 6224217            lock (ThisLock)
 218            {
 6224219                ThrowIfDisposedOrImmutable();
 6224220                State = CommunicationState.Opening;
 6224221            }
 222
 6224223            bool throwing = true;
 224            try
 225            {
 6224226                OnOpening();
 6224227                if (!_onOpeningCalled)
 228                {
 0229                    throw TraceUtility.ThrowHelperError(CreateBaseClassMethodNotCalledException("OnOpening"), Guid.Empty
 230                }
 231
 6224232                await OnOpenAsync(token);
 233
 6224234                OnOpened();
 6214235                if (!_onOpenedCalled)
 236                {
 0237                    throw TraceUtility.ThrowHelperError(CreateBaseClassMethodNotCalledException("OnOpened"), Guid.Empty,
 238                }
 239
 6214240                throwing = false;
 6214241            }
 242            finally
 243            {
 6224244                if (throwing)
 245                {
 246                    //if (DiagnosticUtility.ShouldTraceWarning)
 247                    //{
 248                    //    TraceUtility.TraceEvent(TraceEventType.Warning, TraceCode.CommunicationObjectOpenFailed, SR.Fo
 249                    //}
 250
 10251                    Fault();
 252                }
 253            }
 254            //}
 6214255        }
 256
 257        // TODO: Make internal again
 258        public void Fault(Exception exception)
 259        {
 0260            lock (ThisLock)
 261            {
 0262                if (_exceptionQueue == null)
 263                {
 0264                    _exceptionQueue = new ExceptionQueue(ThisLock);
 265                }
 0266            }
 267
 268            //if (exception != null && DiagnosticUtility.ShouldTraceInformation)
 269            //{
 270            //    TraceUtility.TraceEvent(TraceEventType.Information, TraceCode.CommunicationObjectFaultReason,
 271            //        SR.TraceCodeCommunicationObjectFaultReason, exception, null);
 272            //}
 273
 0274            _exceptionQueue.AddException(exception);
 0275            Fault();
 0276        }
 277
 278        internal void AddPendingException(Exception exception)
 279        {
 0280            lock (ThisLock)
 281            {
 0282                if (_exceptionQueue == null)
 283                {
 0284                    _exceptionQueue = new ExceptionQueue(ThisLock);
 285                }
 0286            }
 287
 0288            _exceptionQueue.AddException(exception);
 0289        }
 290
 291        internal Exception GetPendingException()
 292        {
 0293            CommunicationState currentState = State;
 294
 295            Fx.Assert(currentState == CommunicationState.Closing || currentState == CommunicationState.Closed || current
 296                "CommunicationObject.GetPendingException(currentState == CommunicationState.Closing || currentState == C
 297
 0298            ExceptionQueue queue = _exceptionQueue;
 0299            if (queue != null)
 300            {
 0301                return queue.GetException();
 302            }
 303            else
 304            {
 0305                return null;
 306            }
 307        }
 308
 309        protected void Fault()
 310        {
 16311            lock (ThisLock)
 312            {
 16313                if (State == CommunicationState.Closed || State == CommunicationState.Closing)
 314                {
 5315                    return;
 316                }
 317
 11318                if (State == CommunicationState.Faulted)
 319                {
 0320                    return;
 321                }
 322
 11323                State = CommunicationState.Faulted;
 11324            }
 325
 11326            OnFaulted();
 16327        }
 328
 329        internal void ThrowIfClosed()
 330        {
 10224331            ThrowPending();
 332
 10224333            switch (State)
 334            {
 335                case CommunicationState.Created:
 336                    break;
 337
 338                case CommunicationState.Opening:
 339                    break;
 340
 341                case CommunicationState.Opened:
 342                    break;
 343
 344                case CommunicationState.Closing:
 345                    break;
 346
 347                case CommunicationState.Closed:
 0348                    throw TraceUtility.ThrowHelperError(CreateClosedException(), Guid.Empty, this);
 349
 350                case CommunicationState.Faulted:
 0351                    throw TraceUtility.ThrowHelperError(CreateFaultedException(), Guid.Empty, this);
 352
 353                default:
 0354                    throw Fx.AssertAndThrow("ThrowIfClosed: Unknown CommunicationObject.state");
 355            }
 10224356        }
 357
 358        protected virtual Type GetCommunicationObjectType()
 359        {
 0360            return GetType();
 361        }
 362
 363        protected abstract void OnAbort();
 364
 365        protected abstract Task OnCloseAsync(CancellationToken token);
 366
 367        protected abstract Task OnOpenAsync(CancellationToken token);
 368
 369        protected virtual void OnClosed()
 370        {
 3078371            _onClosedCalled = true;
 372
 3078373            lock (ThisLock)
 374            {
 3078375                if (_raisedClosed)
 376                {
 0377                    return;
 378                }
 379
 3078380                _raisedClosed = true;
 3078381                State = CommunicationState.Closed;
 3078382            }
 383
 384            //if (DiagnosticUtility.ShouldTraceVerbose)
 385            //{
 386            //    TraceUtility.TraceEvent(TraceEventType.Verbose, TraceCode.CommunicationObjectClosed, SR.Format(SR.Trac
 387            //}
 388
 3078389            EventHandler handler = Closed;
 3078390            if (handler != null)
 391            {
 392                try
 393                {
 79394                    handler(EventSender, EventArgs.Empty);
 79395                }
 0396                catch (Exception exception)
 397                {
 0398                    if (Fx.IsFatal(exception))
 399                    {
 0400                        throw;
 401                    }
 402
 0403                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperCallback(exception);
 404                }
 405            }
 3078406        }
 407
 408        protected virtual void OnClosing()
 409        {
 3083410            _onClosingCalled = true;
 411
 3083412            lock (ThisLock)
 413            {
 3083414                if (_raisedClosing)
 415                {
 5416                    return;
 417                }
 418
 3078419                _raisedClosing = true;
 3078420            }
 421
 422            //if (DiagnosticUtility.ShouldTraceVerbose)
 423            //{
 424            //    TraceUtility.TraceEvent(TraceEventType.Verbose, TraceCode.CommunicationObjectClosing, SR.Format(SR.Tra
 425            //}
 3078426            EventHandler handler = Closing;
 3078427            if (handler != null)
 428            {
 429                try
 430                {
 0431                    handler(EventSender, EventArgs.Empty);
 0432                }
 0433                catch (Exception exception)
 434                {
 0435                    if (Fx.IsFatal(exception))
 436                    {
 0437                        throw;
 438                    }
 439
 0440                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperCallback(exception);
 441                }
 442            }
 3083443        }
 444
 445        protected virtual void OnFaulted()
 446        {
 11447            lock (ThisLock)
 448            {
 11449                if (_raisedFaulted)
 450                {
 0451                    return;
 452                }
 453
 11454                _raisedFaulted = true;
 11455            }
 456
 457            //if (DiagnosticUtility.ShouldTraceWarning)
 458            //{
 459            //    TraceUtility.TraceEvent(TraceEventType.Warning, TraceCode.CommunicationObjectFaulted, SR.Format(SR.Tra
 460            //}
 461
 11462            EventHandler handler = Faulted;
 11463            if (handler != null)
 464            {
 465                try
 466                {
 1467                    handler(EventSender, EventArgs.Empty);
 1468                }
 0469                catch (Exception exception)
 470                {
 0471                    if (Fx.IsFatal(exception))
 472                    {
 0473                        throw;
 474                    }
 475
 0476                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperCallback(exception);
 477                }
 478            }
 11479        }
 480
 481        protected virtual void OnOpened()
 482        {
 6224483            _onOpenedCalled = true;
 484
 6224485            lock (ThisLock)
 486            {
 6224487                if (Aborted || State != CommunicationState.Opening)
 488                {
 0489                    return;
 490                }
 491
 6224492                State = CommunicationState.Opened;
 6224493            }
 494
 495            //if (DiagnosticUtility.ShouldTraceVerbose)
 496            //    TraceUtility.TraceEvent(TraceEventType.Verbose, TraceCode.CommunicationObjectOpened, SR.Format(SR.Trac
 497
 6224498            EventHandler handler = Opened;
 6224499            if (handler != null)
 500            {
 501                try
 502                {
 571503                    handler(EventSender, EventArgs.Empty);
 561504                }
 10505                catch (Exception exception)
 506                {
 10507                    if (Fx.IsFatal(exception))
 508                    {
 0509                        throw;
 510                    }
 511
 10512                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperCallback(exception);
 513                }
 514            }
 6214515        }
 516
 517        protected virtual void OnOpening()
 518        {
 6224519            _onOpeningCalled = true;
 520
 521            //if (DiagnosticUtility.ShouldTraceVerbose)
 522            //{
 523            //    TraceUtility.TraceEvent(TraceEventType.Verbose, TraceCode.CommunicationObjectOpening, SR.Format(SR.Tra
 524            //}
 525
 6224526            EventHandler handler = Opening;
 6224527            if (handler != null)
 528            {
 529                try
 530                {
 83531                    handler(EventSender, EventArgs.Empty);
 83532                }
 0533                catch (Exception exception)
 534                {
 0535                    if (Fx.IsFatal(exception))
 536                    {
 0537                        throw;
 538                    }
 539
 0540                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperCallback(exception);
 541                }
 542            }
 6224543        }
 544        internal void ThrowIfFaulted()
 545        {
 44546            ThrowPending();
 547
 44548            switch (State)
 549            {
 550                case CommunicationState.Created:
 551                    break;
 552
 553                case CommunicationState.Opening:
 554                    break;
 555
 556                case CommunicationState.Opened:
 557                    break;
 558
 559                case CommunicationState.Closing:
 560                    break;
 561
 562                case CommunicationState.Closed:
 563                    break;
 564
 565                case CommunicationState.Faulted:
 0566                    throw TraceUtility.ThrowHelperError(CreateFaultedException(), Guid.Empty, this);
 567
 568                default:
 0569                    throw Fx.AssertAndThrow("ThrowIfFaulted: Unknown CommunicationObject.state");
 570            }
 44571        }
 572
 573        internal void ThrowIfAborted()
 574        {
 0575            if (Aborted && !_closeCalled)
 576            {
 0577                throw TraceUtility.ThrowHelperError(CreateAbortedException(), Guid.Empty, this);
 578            }
 0579        }
 580
 581        private Exception CreateNotOpenException()
 582        {
 0583            return new InvalidOperationException(SR.Format(SRCommon.CommunicationObjectCannotBeUsed, GetCommunicationObj
 584        }
 585
 586        private Exception CreateBaseClassMethodNotCalledException(string method)
 587        {
 0588            return new InvalidOperationException(SR.Format(SR.CommunicationObjectBaseClassMethodNotCalled, GetCommunicat
 589        }
 590
 591        private Exception CreateImmutableException()
 592        {
 0593            return new InvalidOperationException(SR.Format(SR.CommunicationObjectCannotBeModifiedInState, GetCommunicati
 594        }
 595
 596        internal Exception CreateClosedException()
 597        {
 0598            if (!_closeCalled)
 599            {
 0600                return CreateAbortedException();
 601            }
 602            else
 603            {
 0604                return new ObjectDisposedException(GetCommunicationObjectType().ToString());
 605            }
 606        }
 607
 608        internal Exception CreateFaultedException()
 609        {
 0610            string message = SR.Format(SR.CommunicationObjectFaulted1, GetCommunicationObjectType().ToString());
 0611            return new CommunicationObjectFaultedException(message);
 612        }
 613
 614        internal Exception CreateAbortedException()
 615        {
 0616            return new CommunicationObjectAbortedException(SR.Format(SR.CommunicationObjectAborted1, GetCommunicationObj
 617        }
 618
 619        protected internal void ThrowIfDisposed()
 620        {
 2481621            ThrowPending();
 622
 2481623            switch (State)
 624            {
 625                case CommunicationState.Created:
 626                    break;
 627
 628                case CommunicationState.Opening:
 629                    break;
 630
 631                case CommunicationState.Opened:
 632                    break;
 633
 634                case CommunicationState.Closing:
 0635                    throw TraceUtility.ThrowHelperError(CreateClosedException(), Guid.Empty, this);
 636
 637                case CommunicationState.Closed:
 0638                    throw TraceUtility.ThrowHelperError(CreateClosedException(), Guid.Empty, this);
 639
 640                case CommunicationState.Faulted:
 0641                    throw TraceUtility.ThrowHelperError(CreateFaultedException(), Guid.Empty, this);
 642
 643                default:
 0644                    throw Fx.AssertAndThrow("ThrowIfDisposed: Unknown CommunicationObject.state");
 645            }
 2481646        }
 647
 648        internal void ThrowIfClosedOrOpened()
 649        {
 640650            ThrowPending();
 651
 640652            switch (State)
 653            {
 654                case CommunicationState.Created:
 655                    break;
 656
 657                case CommunicationState.Opening:
 658                    break;
 659
 660                case CommunicationState.Opened:
 0661                    throw TraceUtility.ThrowHelperError(CreateImmutableException(), Guid.Empty, this);
 662
 663                case CommunicationState.Closing:
 0664                    throw TraceUtility.ThrowHelperError(CreateImmutableException(), Guid.Empty, this);
 665
 666                case CommunicationState.Closed:
 0667                    throw TraceUtility.ThrowHelperError(CreateClosedException(), Guid.Empty, this);
 668
 669                case CommunicationState.Faulted:
 0670                    throw TraceUtility.ThrowHelperError(CreateFaultedException(), Guid.Empty, this);
 671
 672                default:
 0673                    throw Fx.AssertAndThrow("ThrowIfClosedOrOpened: Unknown CommunicationObject.state");
 674            }
 640675        }
 676
 677        protected internal void ThrowIfDisposedOrImmutable()
 678        {
 12263679            ThrowPending();
 680
 12263681            switch (State)
 682            {
 683                case CommunicationState.Created:
 684                    break;
 685
 686                case CommunicationState.Opening:
 0687                    throw TraceUtility.ThrowHelperError(CreateImmutableException(), Guid.Empty, this);
 688
 689                case CommunicationState.Opened:
 0690                    throw TraceUtility.ThrowHelperError(CreateImmutableException(), Guid.Empty, this);
 691
 692                case CommunicationState.Closing:
 0693                    throw TraceUtility.ThrowHelperError(CreateClosedException(), Guid.Empty, this);
 694
 695                case CommunicationState.Closed:
 0696                    throw TraceUtility.ThrowHelperError(CreateClosedException(), Guid.Empty, this);
 697
 698                case CommunicationState.Faulted:
 0699                    throw TraceUtility.ThrowHelperError(CreateFaultedException(), Guid.Empty, this);
 700
 701                default:
 0702                    throw Fx.AssertAndThrow("ThrowIfDisposedOrImmutable: Unknown CommunicationObject.state");
 703            }
 12263704        }
 705
 706        protected internal void ThrowIfDisposedOrNotOpen()
 707        {
 1382708            ThrowPending();
 709
 1382710            switch (State)
 711            {
 712                case CommunicationState.Created:
 0713                    throw TraceUtility.ThrowHelperError(CreateNotOpenException(), Guid.Empty, this);
 714
 715                case CommunicationState.Opening:
 0716                    throw TraceUtility.ThrowHelperError(CreateNotOpenException(), Guid.Empty, this);
 717
 718                case CommunicationState.Opened:
 719                    break;
 720
 721                case CommunicationState.Closing:
 0722                    throw TraceUtility.ThrowHelperError(CreateClosedException(), Guid.Empty, this);
 723
 724                case CommunicationState.Closed:
 0725                    throw TraceUtility.ThrowHelperError(CreateClosedException(), Guid.Empty, this);
 726
 727                case CommunicationState.Faulted:
 0728                    throw TraceUtility.ThrowHelperError(CreateFaultedException(), Guid.Empty, this);
 729
 730                default:
 0731                    throw Fx.AssertAndThrow("ThrowIfDisposedOrNotOpen: Unknown CommunicationObject.state");
 732            }
 1382733        }
 734
 735        public void ThrowIfNotOpened()
 736        {
 109737            if (State == CommunicationState.Created || State == CommunicationState.Opening)
 738            {
 0739                throw TraceUtility.ThrowHelperError(CreateNotOpenException(), Guid.Empty, this);
 740            }
 109741        }
 742
 743        internal void ThrowIfClosedOrNotOpen()
 744        {
 2748745            ThrowPending();
 746
 2748747            switch (State)
 748            {
 749                case CommunicationState.Created:
 0750                    throw TraceUtility.ThrowHelperError(CreateNotOpenException(), Guid.Empty, this);
 751
 752                case CommunicationState.Opening:
 0753                    throw TraceUtility.ThrowHelperError(CreateNotOpenException(), Guid.Empty, this);
 754
 755                case CommunicationState.Opened:
 756                    break;
 757
 758                case CommunicationState.Closing:
 759                    break;
 760
 761                case CommunicationState.Closed:
 0762                    throw TraceUtility.ThrowHelperError(CreateClosedException(), Guid.Empty, this);
 763
 764                case CommunicationState.Faulted:
 0765                    throw TraceUtility.ThrowHelperError(CreateFaultedException(), Guid.Empty, this);
 766
 767                default:
 0768                    throw Fx.AssertAndThrow("ThrowIfClosedOrNotOpen: Unknown CommunicationObject.state");
 769            }
 2748770        }
 771
 772        //TODO: Make internal again
 773        public void ThrowPending()
 774        {
 30188775            ExceptionQueue queue = _exceptionQueue;
 776
 30188777            if (queue != null)
 778            {
 0779                Exception exception = queue.GetException();
 780
 0781                if (exception != null)
 782                {
 0783                    throw TraceUtility.ThrowHelperError(exception, Guid.Empty, this);
 784                }
 785            }
 30188786        }
 787
 788        private class ExceptionQueue
 789        {
 0790            private readonly Queue<Exception> _exceptions = new Queue<Exception>();
 791
 0792            internal ExceptionQueue(object thisLock)
 793            {
 0794                ThisLock = thisLock;
 0795            }
 796
 0797            private object ThisLock { get; }
 798
 799            public void AddException(Exception exception)
 800            {
 0801                if (exception == null)
 802                {
 0803                    return;
 804                }
 805
 0806                lock (ThisLock)
 807                {
 0808                    _exceptions.Enqueue(exception);
 0809                }
 0810            }
 811
 812            public Exception GetException()
 813            {
 0814                lock (ThisLock)
 815                {
 0816                    if (_exceptions.Count > 0)
 817                    {
 0818                        return _exceptions.Dequeue();
 819                    }
 0820                }
 821
 0822                return null;
 0823            }
 824        }
 825    }
 826}