BinaryAsyncLock is a helper primitive that can be used instead of SemaphoreSlim.WaitAsync + double-checked locking
After BinaryAsyncLock is created or reset, the first caller of WaitAsync will immediately get IBinaryAsyncLockToken that is not set. All other callers will either wait until IBinaryAsyncLockToken.Set is called and then will get , or until until IBinaryAsyncLockToken.Reset is called and next awaiting caller will get ,
コード例 #1
0
ファイル: BinaryAsyncLockTest.cs プロジェクト: Microsoft/RTVS
        public async Task WaitAsync_SetInCtor() {
            var bal = new BinaryAsyncLock(true);
            var count = 0;
            await ParallelTools.InvokeAsync(4, async i => {
                await bal.WaitAsync();
                if (!bal.IsSet) {
                    await Task.Delay(50);
                    Interlocked.Increment(ref count);
                }
            });

            count.Should().Be(0);
        }
コード例 #2
0
ファイル: BinaryAsyncLockTest.cs プロジェクト: Microsoft/RTVS
        public async Task WaitAsync_Reset() {
            var bal = new BinaryAsyncLock();
            var count = 0;
            await ParallelTools.InvokeAsync(4, async i => {
                var token = await bal.WaitAsync();
                if (!bal.IsSet) {
                    await Task.Delay(50);
                    Interlocked.Increment(ref count);
                    token.Reset();
                }
            });

            count.Should().Be(4);
        }
コード例 #3
0
        public RPackageManagerViewModel(IRPackageManager packageManager, IRSettings settings, ICoreShell coreShell) {
            _packageManager = packageManager;
            _settings = settings;
            _coreShell = coreShell;
            _selectedTab = Tab.None;
            _availablePackages = new List<IRPackageViewModel>();
            _installedPackages = new List<IRPackageViewModel>();
            _loadedPackages = new List<IRPackageViewModel>();
            _availableLock = new BinaryAsyncLock();
            _installedAndLoadedLock = new BinaryAsyncLock();
            _items = new BatchObservableCollection<object>();
            _errorMessages = new ErrorMessageCollection(this);
            Items = new ReadOnlyObservableCollection<object>(_items);

            _packageManager.AvailablePackagesInvalidated += AvailablePackagesInvalidated;
            _packageManager.InstalledPackagesInvalidated += InstalledPackagesInvalidated;
            _packageManager.LoadedPackagesInvalidated += LoadedPackagesInvalidated;
        }
コード例 #4
0
ファイル: BinaryAsyncLockTest.cs プロジェクト: Microsoft/RTVS
        public void ResetIfNotWaiting_ResetAsync_Skip_WaitAsync_Set() {
            var bal = new BinaryAsyncLock();
            var task = bal.ResetAsync();

            task.Should().BeRanToCompletion();
            bal.IsSet.Should().BeFalse();

            task.Result.Reset();

            bal.IsSet.Should().BeFalse();

            task = bal.WaitAsync();

            task.Should().BeRanToCompletion();
            bal.IsSet.Should().BeFalse();

            task.Result.Set();

            bal.IsSet.Should().BeTrue();
        }
コード例 #5
0
ファイル: BinaryAsyncLock.cs プロジェクト: Microsoft/RTVS
 public TokenSource(BinaryAsyncLock binaryAsyncLock) {
     Task = System.Threading.Tasks.Task.FromResult<IBinaryAsyncLockToken>(new Token(binaryAsyncLock, this));
 }
コード例 #6
0
ファイル: BinaryAsyncLock.cs プロジェクト: Microsoft/RTVS
 public Token(BinaryAsyncLock binaryAsyncLock, TokenSource tokenSource) {
     _binaryAsyncLock = binaryAsyncLock;
     _tokenSource = tokenSource;
     IsSet = false;
 }
コード例 #7
0
 public TokenSource(BinaryAsyncLock binaryAsyncLock)
 {
     Task = System.Threading.Tasks.Task.FromResult <IBinaryAsyncLockToken>(new Token(binaryAsyncLock, this));
 }
コード例 #8
0
 public Token(BinaryAsyncLock binaryAsyncLock, TokenSource tokenSource)
 {
     _binaryAsyncLock = binaryAsyncLock;
     _tokenSource     = tokenSource;
     IsSet            = false;
 }
コード例 #9
0
ファイル: BinaryAsyncLockTest.cs プロジェクト: Microsoft/RTVS
        public void WaitAsync_ResetAsync_Set() {
            var bal = new BinaryAsyncLock();
            var task1 = bal.WaitAsync();
            var task2 = bal.ResetAsync();

            task1.Result.Set();

            task1.Should().BeRanToCompletion();
            task2.Should().BeRanToCompletion();
            bal.IsSet.Should().BeFalse();
        }
コード例 #10
0
ファイル: BinaryAsyncLockTest.cs プロジェクト: Microsoft/RTVS
        public void CancelEven() {
            var bal = new BinaryAsyncLock(true);
            var cts = new CancellationTokenSource();
            var task1 = bal.ResetAsync();
            var task2 = bal.ResetAsync(cts.Token);
            var task3 = bal.ResetAsync(cts.Token);
            var task4 = bal.WaitAsync();
            var task5 = bal.WaitAsync(cts.Token);

            task1.Should().BeRanToCompletion();
            task2.Should().NotBeCompleted();
            task3.Should().NotBeCompleted();
            task4.Should().NotBeCompleted();
            task5.Should().NotBeCompleted();

            cts.Cancel();
            task1.Should().BeRanToCompletion();
            task2.Should().BeCanceled();
            task3.Should().BeCanceled();
            task4.Should().NotBeCompleted();
            task5.Should().BeCanceled();

            task1.Result.Reset();
            task1.Should().BeRanToCompletion();
            task2.Should().BeCanceled();
            task3.Should().BeCanceled();
            task4.Should().BeRanToCompletion();
            task5.Should().BeCanceled();

            bal.IsSet.Should().BeFalse();
        }
コード例 #11
0
ファイル: BinaryAsyncLockTest.cs プロジェクト: Microsoft/RTVS
        public void CancelResetAsync_Set() {
            var bal = new BinaryAsyncLock(true);
            var cts = new CancellationTokenSource();
            var tasks = Enumerable.Range(0, 4).Select(i => bal.ResetAsync(cts.Token)).ToList();
            tasks.Should().ContainSingle(t => t.IsCompleted);

            cts.Cancel();
            tasks.Should().OnlyContain(t => t.IsCompleted);
        }
コード例 #12
0
ファイル: BinaryAsyncLockTest.cs プロジェクト: Microsoft/RTVS
        public void CancelWaitAsync_Set() {
            var bal = new BinaryAsyncLock(true);
            var cts = new CancellationTokenSource();
            var tasks = Enumerable.Range(0, 4).Select(i => bal.WaitAsync(cts.Token)).ToList();
            tasks.Should().OnlyContain(t => t.Status == TaskStatus.RanToCompletion);

            cts.Cancel();
            tasks.Should().OnlyContain(t => t.Status == TaskStatus.RanToCompletion);
        }
コード例 #13
0
ファイル: BinaryAsyncLockTest.cs プロジェクト: Microsoft/RTVS
        public void SequentalWaitReset_SetToken() {
            var bal = new BinaryAsyncLock(true);
            var task1 = bal.ResetAsync();
            var task2 = bal.WaitAsync();
            var task3 = bal.ResetAsync();
            var task4 = bal.WaitAsync();
            var task5 = bal.ResetAsync();

            task1.Should().BeRanToCompletion();
            task2.Should().NotBeCompleted();
            task3.Should().NotBeCompleted();
            task4.Should().NotBeCompleted();
            task5.Should().NotBeCompleted();
            bal.IsSet.Should().BeFalse();

            task1.Result.Set();

            task1.Should().BeRanToCompletion();
            task2.Should().BeRanToCompletion();
            task3.Should().BeRanToCompletion();
            task4.Should().NotBeCompleted();
            task5.Should().NotBeCompleted();
            bal.IsSet.Should().BeFalse();

            task3.Result.Set();

            task1.Should().BeRanToCompletion();
            task2.Should().BeRanToCompletion();
            task3.Should().BeRanToCompletion();
            task4.Should().BeRanToCompletion();
            task5.Should().BeRanToCompletion();
            bal.IsSet.Should().BeFalse();
        }
コード例 #14
0
ファイル: BinaryAsyncLockTest.cs プロジェクト: Microsoft/RTVS
        public void ResetAsync_ResetAsync_WaitAsync_CancelSecond_SetFirst() {
            var bal = new BinaryAsyncLock(true);
            var cts = new CancellationTokenSource();

            var task1 = bal.ResetAsync();
            var task2 = bal.ResetAsync(cts.Token);
            var task3 = bal.WaitAsync();

            cts.Cancel();
            task1.Result.Set();

            task1.Should().BeRanToCompletion();
            task2.Should().BeCanceled();
            task3.Should().BeRanToCompletion();
            bal.IsSet.Should().BeTrue();
        }
コード例 #15
0
ファイル: BinaryAsyncLockTest.cs プロジェクト: Microsoft/RTVS
        public void ResetAsync_ResetAsync_Set_SetIfLast() {
            var bal = new BinaryAsyncLock();
            var task1 = bal.ResetAsync();
            var task2 = bal.ResetAsync();

            task1.Result.Set();
            task2.Result.SetIfLast();

            task1.Should().BeRanToCompletion();
            task2.Should().BeRanToCompletion();
            bal.IsSet.Should().BeTrue();
        }