Пример #1
0
        // TODO:
        // Hardcode a time out value for cancellation token.
        // For some time consuming operations, this time out needs to be tuned.
        public static Task BatchProcess <T>(IList <T> source, Func <T, Task> f, int max)
        {
            var initial = (max >> 1);
            var s       = new System.Threading.SemaphoreSlim(initial, max);

            _ = Task.Run(async() =>
            {
                for (int i = initial; i < max; i++)
                {
                    await Task.Delay(100);
                    s.Release();
                }
            });

            return(Task.WhenAll(from item in source
                                select Task.Run(async() =>
            {
                await s.WaitAsync();
                try
                {
                    await f(item);
                }
                catch (Exception e)
                {
                    Log.Warning($"see exception in {f.Method.Name}: {e.Message}");
                }
                finally
                {
                    s.Release();
                }
            })));
        }
Пример #2
0
        public void ProducerShouldReportCorrectAmountOfAsyncRequests()
        {
            var semaphore = new SemaphoreSlim(0);
            var routerProxy = new FakeBrokerRouter();
            //block the second call returning from send message async
            routerProxy.BrokerConn0.ProduceResponseFunction = () => { semaphore.Wait(); return new ProduceResponse(); };

            var router = routerProxy.Create();
            using (var producer = new Producer(router, maximumAsyncRequests: 1) { BatchSize = 1 })
            {
                var messages = new[] { new Message("1") };

                Assert.That(producer.AsyncCount, Is.EqualTo(0));

                var sendTask = producer.SendMessageAsync(BrokerRouterProxy.TestTopic, messages);

                TaskTest.WaitFor(() => producer.AsyncCount > 0);
                Assert.That(producer.AsyncCount, Is.EqualTo(1), "One async operation should be sending.");

                semaphore.Release();
                sendTask.Wait(TimeSpan.FromMilliseconds(500));

                Assert.That(sendTask.IsCompleted, Is.True, "Send task should be marked as completed.");
                Assert.That(producer.AsyncCount, Is.EqualTo(0), "Async should now show zero count.");
            }
        }
 private static void TaskMain(SemaphoreSlim semaphore)
 {
     bool isCompleted = false;
     while (!isCompleted)
     {
         if (semaphore.Wait(600))
         {
             try
             {
                 WriteLine($"Task {Task.CurrentId} locks the semaphore");
                 Task.Delay(2000).Wait();
             }
             finally
             {
                 WriteLine($"Task {Task.CurrentId} releases the semaphore");
                 semaphore.Release();
                 isCompleted = true;
             }
         }
         else
         {
             WriteLine($"Timeout for task {Task.CurrentId}; wait again");
         }
     }
 }
        private async Task ExclusiveTask(SemaphoreSlim s, Integer count, int seed, int iteration, bool due)
        {
            var r = new Random(seed);

            if (due)
            {
                try
                {
                    await Delay(r).ConfigureAwait(false);
                }
                catch { }
            }

            for (int i = 0; i < iteration; i++)
            {
                int localCount = 0;
                try
                {
                    await s.WaitAsync();
                    localCount = count.Value;
                    await Delay(r).ConfigureAwait(false);
                }
                catch (TestException) { }
                finally
                {
                    count.Value = localCount + 1;
                    s.Release();
                }
            }
        }
Пример #5
0
        public void Execute(IJobExecutionContext context) {
            var stopwatch = new Stopwatch();
            stopwatch.Start();

            Logger.Info("开始抓取一号店数据");

            var downloadedCategories = new YhdCategoryExtractor().Extract().Result;
            var needProcessCategories = _CategoryArchiveService.Archive(downloadedCategories).OrderBy(c => c.ProductsUpdateTime);
            
            var taskLock = new SemaphoreSlim(initialCount: 1);
            var tasks = needProcessCategories.Select(async (category, index) => {
                await taskLock.WaitAsync();
                try {
                    var result = await ProcessCategoryAsync(category);
                    //■◆▲●□◇△○
                    Logger.Info(string.Join(" ", new[]{
                            string.Format("{0}", index + 1),
                            string.Format("[{0}]{1}", category.Number, category.Name),
                            string.Format("□{0} △{1}", result.Total, result.Changed)
                        }));
                }
                catch (Exception e) {
                    Logger.ErrorFormat("处理分类{0}{1}失败", e, category.Name, category.Number);
                }
                finally {
                    taskLock.Release();
                }
            });

            Task.WaitAll(tasks.ToArray());

            Logger.InfoFormat("抓取一号店数据完成,用时{0:0.#}分", stopwatch.Elapsed.TotalMinutes);
        }
Пример #6
0
 internal BufferStream()
 {
     _readLock = new SemaphoreSlim(1, 1);
     _writeLock = new SemaphoreSlim(1, 1);
     _bufferedData = new ConcurrentQueue<byte[]>();
     _readWaitingForData = new TaskCompletionSource<object>();
 }
Пример #7
0
        static void Main(string[] args)
        {
            // initialize the semaphores
            semA = new SemaphoreSlim(2);
            semB = new SemaphoreSlim(2);

            // define the number of tasks we will use
            int taskCount = 10;

            // initialize the barrier
            cdEvent = new CountdownEvent(taskCount);

            Task[] tasks = new Task[10];
            for (int i = 0; i < taskCount; i++) {
                tasks[i] = Task.Factory.StartNew((stateObject) => {
                    InitialMethod((int)stateObject);
                    Console.WriteLine("Task {0} completed", Task.CurrentId);
                }, i);
            }

            // wait for all of the tasks to have reached a terminal method
            cdEvent.Wait();

            // throw an exception to force the debugger to break
            throw new Exception();
        }
 public FriendRequestsViewModel()
 {
     Items = new ObservableCollection<OneFriendRequestViewModel>();
     Items.CollectionChanged += FriendRequestsCollectionChangedHandler;
     ToxModel.Instance.FriendRequestReceived += FriendRequestReceivedHandler;
     _semaphore = new SemaphoreSlim(1);
 }
        private async Task TestCancelWaitAsyncInternal()
        {
            var r = new Random();
            var s = new SemaphoreSlim(1);

            await Task.WhenAll(Enumerable.Range(0, 100).Select(async i =>
            {
                var ct = CancellationToken.None;
                if ((i % 5) == 0)
                {
                    var cts = new CancellationTokenSource();
                    var t = Task.Delay(1).ContinueWith(_ => cts.Cancel());
                    ct = cts.Token;
                }

                try
                {
                    await s.WaitAsync(ct);
                    await Delay(r, ct).ConfigureAwait(false);
                }
                catch (TestException) { }
                catch (OperationCanceledException) { }
                finally
                {
                    s.Release();
                }
            }));
        }
Пример #10
0
 /// <summary>
 /// Initialises a new instance of the <see cref="BaseClient"/> class.
 /// </summary>
 /// <param name="byteStream">The byte stream.</param>
 /// <param name="token">The token.</param>
 protected BaseClient(IByteStream byteStream, CancellationToken token)
 {
   this.ByteStream = byteStream;
   this.SendRateLimit = new SemaphoreSlim(1);
   this.InternalCancellation = new CancellationTokenSource();
   token.Register(() => this.InternalCancellation.Cancel());
 }
Пример #11
0
        internal AudioPlayer()
        {
            this.audioPlayerCallback = new DummyMediaPlayerCallback();
            this.videoPlayerCallback = new DummyMediaPlayerCallback();
            this.currentCallback = new DummyMediaPlayerCallback();

            this.finishSubscription = new SerialDisposable();
            this.gate = new SemaphoreSlim(1, 1);

            this.playbackState = new BehaviorSubject<AudioPlayerState>(AudioPlayerState.None);
            this.PlaybackState = this.playbackState.DistinctUntilChanged();

            this.loadedSong = new BehaviorSubject<Song>(null);
            this.TotalTime = this.loadedSong.Select(x => x == null ? TimeSpan.Zero : x.Duration);

            this.currentTimeChangedFromOuter = new Subject<TimeSpan>();

            var conn = Observable.Interval(TimeSpan.FromMilliseconds(300), RxApp.TaskpoolScheduler)
                .CombineLatest(this.PlaybackState, (l, state) => state)
                .Where(x => x == AudioPlayerState.Playing)
                .Select(_ => this.CurrentTime)
                .Merge(this.currentTimeChangedFromOuter)
                .DistinctUntilChanged(x => x.TotalSeconds)
                .Publish(TimeSpan.Zero);
            conn.Connect();
            this.CurrentTimeChanged = conn;
        }
 static void TaskMain(SemaphoreSlim semaphore)
 {
     bool isCompleted = false;
       while (!isCompleted)
       {
     if (semaphore.Wait(600))
     {
       try
       {
     Console.WriteLine("Task {0} locks the semaphore", Task.CurrentId);
     Thread.Sleep(2000);
       }
       finally
       {
     Console.WriteLine("Task {0} releases the semaphore", Task.CurrentId);
     semaphore.Release();
     isCompleted = true;
       }
     }
     else
     {
       Console.WriteLine("Timeout for task {0}; wait again",
      Task.CurrentId);
     }
       }
 }
 public AwaitingConnectedSpheroRunner(IStreamSocketWrapper streamSpheroWrapper)
 {
     _streamSpheroWrapper = streamSpheroWrapper;
     _itemsToSendEvent = new SemaphoreSlim(1);
     _itemsToSendEvent.Wait();
     _commandsToSend = new Queue<CommandWithActions>();
 }
Пример #14
0
        public void ExtremeDisposal()
        {
            using (var context = CreateContext())
            {
                Assert.AreEqual(-1, context.Publisher.MySettings.MaxConnectionRetry, "For this test, we want the worst situation");

                context.Publisher.Start(0);
                Assert.IsTrue(context.Publisher.Started);

                var message = new byte[] { 0, 1, 1 };
                var connectionFail = new SemaphoreSlim(0);
                context.Model.Setup(m => m.BasicPublish(It.IsAny<string>(), It.IsAny<string>(), context.Publisher.Props, message)).Throws(new Exception("I don't want your message anymore"));
                context.Connection.Setup(c => c.CreateModel()).Callback(() => connectionFail.Release(1)).Throws(new Exception("And I don't want to accept your connection either"));

                context.Publisher.Publish("test", message);

                /* The way callbacks are implemented on exception throwing mocks does not garantee
                 * that the callback is called "after" the exception is thrown.
                 * If we wait for two, we are sure at least one has been finished !
                 */
                Assert.IsTrue(connectionFail.Wait(1000));
                Assert.IsTrue(connectionFail.Wait(1000));

                context.Publisher.Dispose();
                context.Publisher = null; //to avoid the double dispose of Publisher
                //The real test here is that eventually the Dispose method returns
                Assert.Pass();
            }
        }
Пример #15
0
    public static async Task <T> DeserializeAsync <T>(Windows.Storage.StorageFile f, System.Threading.SemaphoreSlim semaphore) where T : class
    {
        await semaphore.WaitAsync();

        try
        {
            if (f is null)
            {
                return(null);
            }
            using var s1 = await f.OpenAsync(Windows.Storage.FileAccessMode.Read);

            using var s2 = s1.AsStream();
            var serializer = new System.Xml.Serialization.XmlSerializer(typeof(T));
            return(serializer.Deserialize(s2) as T);
        }
        catch
        {
            return(null);
        }
        finally
        {
            semaphore.Release();
        }
    }
        public static bool CancelAfterWait()
        {
            TestHarness.TestLog("* SemaphoreSlimCancellationTests.CancelAfterWait()");
            bool passed = true;

            CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
            CancellationToken cancellationToken = cancellationTokenSource.Token;

            SemaphoreSlim semaphoreSlim = new SemaphoreSlim(0); // semaphore that will block all waiters
            
            ThreadPool.QueueUserWorkItem(
                (args) =>
                {
                    Thread.Sleep(1000);
                    cancellationTokenSource.Cancel();
                }
                );

            //Now wait.. the wait should abort and an exception should be thrown
            passed &= TestHarnessAssert.EnsureOperationCanceledExceptionThrown(
                () => semaphoreSlim.Wait(cancellationToken),
                cancellationToken, "An OCE(null) should have been thrown that references the cancellationToken.");

            // the token should not have any listeners.
            // currently we don't expose this.. but it was verified manually

            return passed;
        }
Пример #17
0
		/// <summary>
		/// Initializes a new instance of the <see cref="FFImageLoading.Cache.DiskCache"/> class.
		/// </summary>
		/// <param name="basePath">Base path.</param>
		/// <param name="version">Version.</param>
        public DiskCache(string basePath, string version)
        {
            // Can't use minilogger here, we would have too many dependencies
            System.Diagnostics.Debug.WriteLine("DiskCache path: " + basePath);

            this.basePath = basePath;

            if (!Directory.Exists(basePath))
                Directory.CreateDirectory(basePath);
			
            this.journalPath = Path.Combine(basePath, JournalFileName);
            this.version = version;
			this.lockJournal = new object();
			this.fileWriteLock = new SemaphoreSlim(initialCount: 1);
			this.fileWritePendingTasks = new ConcurrentDictionary<string, byte>();

            try 
			{
                InitializeWithJournal ();
            } 
			catch 
			{
                Directory.Delete (basePath, true);
                Directory.CreateDirectory (basePath);
            }

            ThreadPool.QueueUserWorkItem(CleanCallback);
        }
        public async Task<TokenPair> Authorize(string clientId, string clientSecret, IEnumerable<string> scopes)
        {
            string uri = string.Format("/LoginPage.xaml?authEndpoint={0}&clientId={1}&scope={2}",
                                       authEndpoint,
                                       clientId,
                                       string.Join(" ", scopes));

            SemaphoreSlim semaphore = new SemaphoreSlim(0, 1);

            Observable.FromEvent<NavigatingCancelEventHandler, NavigatingCancelEventArgs>(
                h => new NavigatingCancelEventHandler(h),
                h => this.frame.Navigating += h,
                h => this.frame.Navigating -= h)
                      .SkipWhile(h => h.EventArgs.NavigationMode != NavigationMode.Back)
                      .Take(1)
                      .Subscribe(e => semaphore.Release());

            frame.Navigate(new Uri(uri, UriKind.Relative));

            await semaphore.WaitAsync();

            string authorizationCode = (string)PhoneApplicationService.Current.State["OAuth_Demo.AuthorizationCode"];

            return await RequestAccessToken(authorizationCode, clientId, clientSecret);
        }
        internal WebSocketConnectionRfc6455(Stream clientStream, WebSocketListenerOptions options)
        {
            if (clientStream == null)
                throw new ArgumentNullException("clientStream");

            if (options == null)
                throw new ArgumentNullException("options");

            _writeSemaphore = new SemaphoreSlim(1);
            _options = options;
            
            _clientStream = clientStream;

            if (options.BufferManager != null)
                _buffer = options.BufferManager.TakeBuffer(14 + 125 + 125 + 8 + 10 + _options.SendBufferSize + 4 + 2);
            else
                _buffer = new Byte[14 + 125 + 125 + 8 + 10 + _options.SendBufferSize  + 4 + 2];

            _headerBuffer = new ArraySegment<Byte>(_buffer, 0, 14);
            _controlBuffer = new ArraySegment<Byte>(_buffer, 14, 125);
            _pongBuffer = new ArraySegment<Byte>(_buffer, 14 + 125, 125);
            _pingBuffer = new ArraySegment<Byte>(_buffer, 14 + 125 + 125, 8);
            SendBuffer = new ArraySegment<Byte>(_buffer, 14 + 125 + 125 + 8 + 10, _options.SendBufferSize);
            _keyBuffer = new ArraySegment<Byte>(_buffer, 14 + 125 + 125 + 8 + 10 + _options.SendBufferSize, 4);
            _closeBuffer = new ArraySegment<Byte>(_buffer, 14 + 125 + 125 + 8 + 10 + _options.SendBufferSize + 4, 2);

            _pingTimeout = _options.PingTimeout;
            _pingInterval = TimeSpan.FromMilliseconds(Math.Min(500, _options.PingTimeout.TotalMilliseconds / 2));
        }
 public async Task<AuthorizationResult> AcquireAuthorizationAsync(Uri authorizationUri, Uri redirectUri, IDictionary<string, string> additionalHeaders, CallState callState)
 {
     returnedUriReady = new SemaphoreSlim(0);
     Authenticate(authorizationUri, redirectUri, additionalHeaders, callState);
     await returnedUriReady.WaitAsync().ConfigureAwait(false);
     return authorizationResult;
 }
        // constructors
        public ExclusiveConnectionPool(
            ServerId serverId,
            EndPoint endPoint,
            ConnectionPoolSettings settings,
            IConnectionFactory connectionFactory,
            IEventSubscriber eventSubscriber)
        {
            _serverId = Ensure.IsNotNull(serverId, nameof(serverId));
            _endPoint = Ensure.IsNotNull(endPoint, nameof(endPoint));
            _settings = Ensure.IsNotNull(settings, nameof(settings));
            _connectionFactory = Ensure.IsNotNull(connectionFactory, nameof(connectionFactory));
            Ensure.IsNotNull(eventSubscriber, nameof(eventSubscriber));

            _connectionHolder = new ListConnectionHolder(eventSubscriber);
            _poolQueue = new WaitQueue(settings.MaxConnections);
            _waitQueue = new SemaphoreSlim(settings.WaitQueueSize);
            _maintenanceCancellationTokenSource = new CancellationTokenSource();
            _state = new InterlockedInt32(State.Initial);

            eventSubscriber.TryGetEventHandler(out _checkingOutConnectionEventHandler);
            eventSubscriber.TryGetEventHandler(out _checkedOutConnectionEventHandler);
            eventSubscriber.TryGetEventHandler(out _checkingOutConnectionFailedEventHandler);
            eventSubscriber.TryGetEventHandler(out _checkingInConnectionEventHandler);
            eventSubscriber.TryGetEventHandler(out _checkedInConnectionEventHandler);
            eventSubscriber.TryGetEventHandler(out _addingConnectionEventHandler);
            eventSubscriber.TryGetEventHandler(out _addedConnectionEventHandler);
            eventSubscriber.TryGetEventHandler(out _openingEventHandler);
            eventSubscriber.TryGetEventHandler(out _openedEventHandler);
            eventSubscriber.TryGetEventHandler(out _closingEventHandler);
            eventSubscriber.TryGetEventHandler(out _closedEventHandler);
            eventSubscriber.TryGetEventHandler(out _addingConnectionEventHandler);
            eventSubscriber.TryGetEventHandler(out _addedConnectionEventHandler);
        }
Пример #22
0
 public ConcurrentRunner(int maxThread, int loopEach, AutoResetEvent signal = null)
 {
     this.maxThread = maxThread;
     this.loopEach = loopEach;
     this.semaphore = new SemaphoreSlim(0, maxThread);
     this.signal = signal;
 }
Пример #23
0
        //####################################################################################################################################################################

        public GitHubUtils()
        {
            _settingsHelper = new SettingsHelper(this.GetType().Assembly);
            GitHubReleases.CollectionChanged += GitHubReleases_CollectionChanged;
            SemaphoreGetReleases              = new System.Threading.SemaphoreSlim(0, 1);
            Task.Run(async() => await GetAllGitHubReleases());
        }
Пример #24
0
        // WIP, not producing useful numbers yet. Assumes one partition.
        public static async Task<long> Consume(string broker, string topic)
        {
            long n = 0;

            var topicConfig = new TopicConfig();
            topicConfig["auto.offset.reset"] = "smallest";
            var config = new Config()
            {
                GroupId = "benchmark-consumer",
                DefaultTopicConfig = topicConfig
            };
            using (var consumer = new EventConsumer(config, broker))
            {
                var signal = new SemaphoreSlim(0, 1);

                consumer.OnMessage += (obj, msg) =>
                {
                    n += 1;
                };

                consumer.OnEndReached += (obj, end) =>
                {
                    Console.WriteLine($"End reached");
                    signal.Release();
                };

                consumer.Subscribe(new List<string>{topic});
                consumer.Start();

                await signal.WaitAsync();
                Console.WriteLine($"Shutting down");
            }

            return n;
        }
Пример #25
0
 public ConcurrentRunner(int maxThread, int loopEach)
 {
     this.maxThread = maxThread;
     this.loopEach = loopEach;
     this.semaphore = new SemaphoreSlim(0, maxThread);
     this.countdown = new CountdownEvent(maxThread);
 }
Пример #26
0
 public QueueProcessor(int maxConcurrentJobs, JobQueue jobQueue)
 {
     _semaphore = new SemaphoreSlim(maxConcurrentJobs);
     _jobQueue = jobQueue;
     Task.Factory.StartNew(TaskStartLoop, _cancellationTokenSource.Token);
     _jobQueue.JobAdded += JobQueueOnJobAdded;
 }
        public HttpNegotiationQueue(WebSocketFactoryCollection standards, WebSocketConnectionExtensionCollection extensions, WebSocketListenerOptions options)
        {
            Guard.ParameterCannotBeNull(standards, "standards");
            Guard.ParameterCannotBeNull(extensions, "extensions");
            Guard.ParameterCannotBeNull(options, "options");

            _options = options;
            _extensions = extensions;
            _cancel = new CancellationTokenSource();
            _semaphore = new SemaphoreSlim(options.ParallelNegotiations);
            
            _sockets = new BufferBlock<Socket>(new DataflowBlockOptions()
            {
                BoundedCapacity = options.NegotiationQueueCapacity,
                CancellationToken = _cancel.Token
            });

            _negotiations = new BufferBlock<WebSocketNegotiationResult>(new DataflowBlockOptions()
            {
                BoundedCapacity = options.NegotiationQueueCapacity,
                CancellationToken = _cancel.Token,
            });

            _cancel.Token.Register(_sockets.Complete);
            _cancel.Token.Register(_negotiations.Complete);

            _handShaker = new WebSocketHandshaker(standards, _options);

            Task.Run((Func<Task>)WorkAsync);
        }
Пример #28
0
		public static async Task<HttpResponseMessage> GetWithRetryAsync(this HttpClient client, string url, SemaphoreSlim semaphore, params int[] retryDelay)
		{
			if (retryDelay.Any(delay => delay <= 0))
			{
				throw new ArgumentException("Delay should be greate than 0.", nameof(retryDelay));
			}

			await semaphore.WaitAsync();
			try
			{
				int retryCount = 0;
				while (true)
				{
					try
					{
						return await client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead);
					}
					catch (TaskCanceledException)
					{
						if (retryCount >= retryDelay.Length)
						{
							throw;
						}
					}
					await Task.Delay(retryDelay[retryCount]);
					retryCount++;
				}
			}
			finally
			{
				semaphore.Release();
			}
		}
Пример #29
0
    static int Main(string[] args)
    {
        SemaphoreSlim s = new SemaphoreSlim(initialCount: 1);

        var cts = new CancellationTokenSource();
        s.Wait();
        var t = s.WaitAsync(cts.Token);
        s.Release();
        cts.Cancel();


        if (t.Status != TaskStatus.Canceled && s.CurrentCount == 0)
        {
            Console.WriteLine("PASS");
            return 100;
        }
        else
        {
            Console.WriteLine("FAIL");
            Console.WriteLine("Expected task status to not be Canceled and s.CurrentCount == 0");
            Console.WriteLine("Actual: Task: " + t.Status + "; CurrentCount: " + s.CurrentCount);
            return 101;
        }


    }
Пример #30
0
        /// <summary>
        /// Ensures the list.
        /// </summary>
        /// <param name="url">The URL.</param>
        /// <param name="file">The file.</param>
        /// <param name="httpClient">The HTTP client.</param>
        /// <param name="fileSystem">The file system.</param>
        /// <param name="semaphore">The semaphore.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns>Task.</returns>
        public static async Task EnsureList(string url, string file, IHttpClient httpClient, IFileSystem fileSystem, SemaphoreSlim semaphore, CancellationToken cancellationToken)
        {
            var fileInfo = fileSystem.GetFileInfo(file);

            if (!fileInfo.Exists || (DateTime.UtcNow - fileSystem.GetLastWriteTimeUtc(fileInfo)).TotalDays > 1)
            {
                await semaphore.WaitAsync(cancellationToken).ConfigureAwait(false);

                try
                {
                    var temp = await httpClient.GetTempFile(new HttpRequestOptions
                    {
                        CancellationToken = cancellationToken,
                        Progress = new Progress<double>(),
                        Url = url

                    }).ConfigureAwait(false);

					fileSystem.CreateDirectory(Path.GetDirectoryName(file));

					fileSystem.CopyFile(temp, file, true);
                }
                finally
                {
                    semaphore.Release();
                }
            }
        }
Пример #31
0
        private ServiceContext()
        {
            _Slots = new List<ServiceSlot>();

            _StartSemaphore = new SemaphoreSlim(0);
            _StopSemaphore = new SemaphoreSlim(0);
        }
Пример #32
0
 /// <summary>
 /// Construct a Producer class.
 /// </summary>
 /// <param name="brokerRouter">The router used to direct produced messages to the correct partition.</param>
 /// <param name="maximumAsyncQueue">The maximum async calls allowed before blocking new requests.  -1 indicates unlimited.</param>
 /// <remarks>
 /// The maximumAsyncQueue parameter provides a mechanism for blocking an async request return if the amount of requests queue is 
 /// over a certain limit.  This is usefull if a client is trying to push a large stream of documents through the producer and
 /// wants to block downstream if the producer is overloaded.
 /// 
 /// A message will start its timeout countdown as soon as it is added to the producer async queue.  If there are a large number of 
 /// messages sitting in the async queue then a message may spend its entire timeout cycle waiting in this queue and never getting
 /// attempted to send to Kafka before a timeout exception is thrown.
 /// </remarks>
 public Producer(IBrokerRouter brokerRouter, int maximumAsyncQueue = -1)
 {
     _router = brokerRouter;
     _metadataQueries = new MetadataQueries(_router);
     _maximumAsyncQueue = maximumAsyncQueue == -1 ? int.MaxValue : maximumAsyncQueue;
     _sendSemaphore = new SemaphoreSlim(_maximumAsyncQueue, _maximumAsyncQueue);
 }
Пример #33
0
        public void AsyncLockShouldAllowOnlyOneThread()
        {
            var block = new SemaphoreSlim(0, 2);
            var count = 0;
            var alock = new AsyncLock();

            var firstCall = Task.Factory.StartNew(async () =>
            {
                using (await alock.LockAsync())
                {
                    Interlocked.Increment(ref count);
                    block.Wait();
                }
                block.Wait();//keep this thread busy
            });

            TaskTest.WaitFor(() => count > 0);

            alock.LockAsync().ContinueWith(t => Interlocked.Increment(ref count));

            Assert.That(count, Is.EqualTo(1), "Only one task should have gotten past lock.");
            Assert.That(firstCall.IsCompleted, Is.False, "Task should still be running.");

            block.Release();
            TaskTest.WaitFor(() => count > 1);
            Assert.That(count, Is.EqualTo(2), "Second call should get past lock.");
            Assert.That(firstCall.IsCompleted, Is.False, "First call should still be busy.");
            block.Release();
        }
Пример #34
0
        public static Task <TOut[]> BatchProcess <T, TOut>(IList <T> source, Func <T, Task <TOut> > f, int max)
        {
            var initial = (max >> 1);
            var s       = new System.Threading.SemaphoreSlim(initial, max);

            _ = Task.Run(async() =>
            {
                for (int i = initial; i < max; i++)
                {
                    await Task.Delay(100);
                    s.Release();
                }
            });

            return(Task.WhenAll(from item in source
                                select Task.Run(async() =>
            {
                TOut ret = default;
                var retry = 0;
                var maxRetry = 5;
                while (retry < maxRetry)
                {
                    try
                    {
                        using (var cancellationTokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(60)))
                        {
                            await s.WaitAsync(cancellationTokenSource.Token);
                            try
                            {
                                ret = await f(item);
                                break;
                            }
                            catch (System.OperationCanceledException e)
                            {
                                Log.Warning($"see cancellation in {f.Method.Name}: {e.Message}");
                            }
                            finally
                            {
                                s.Release();
                            }
                        }
                    }
                    catch (System.OperationCanceledException)
                    {
                        Log.Warning($"Waiting too long time to obtain the semaphore: current: {s.CurrentCount}, max: {max}");
                    }
                    var rand = new Random();
                    var randomDelay = TimeSpan.FromMilliseconds(rand.Next(1, 500));
                    await Task.Delay(randomDelay);
                    retry++;
                }
                if (retry == maxRetry)
                {
                    Log.Error($"The operation {f.Method.Name} was canceled because of reaching max retry {maxRetry}");
                }
                return ret;
            })));
        }
Пример #35
0
        public async Task <object> RoundtripMethodCallAsync(string connectionId, string methodName, MethodRequestAndResponse requestAndResponse)
        {
            Console.WriteLine("RoundtripMethodCallAsync received for {0} and methodName {1}", connectionId, methodName);
            Console.WriteLine(JsonConvert.SerializeObject(requestAndResponse));
            var client = objectMap[connectionId];
            var mutex  = new System.Threading.SemaphoreSlim(1);
            await mutex.WaitAsync().ConfigureAwait(false);  // Grab the mutex. The handler will release it later

            MethodCallback callback = async(methodRequest, userContext) =>
            {
                Console.WriteLine("Method invocation received");

                object request  = JsonConvert.DeserializeObject(methodRequest.DataAsJson);
                string received = JsonConvert.SerializeObject(new JRaw(request));
                string expected = ((Newtonsoft.Json.Linq.JToken)requestAndResponse.RequestPayload)["payload"].ToString();
                Console.WriteLine("request expected: " + expected);
                Console.WriteLine("request received: " + received);
                if (expected != received)
                {
                    Console.WriteLine("request did not match expectations");
                    Console.WriteLine("Releasing the method mutex");
                    mutex.Release();
                    return(new MethodResponse(500));
                }
                else
                {
                    int status = 200;
                    if (requestAndResponse.StatusCode != null)
                    {
                        status = (int)requestAndResponse.StatusCode;
                    }

                    byte[] responseBytes = GlueUtils.ObjectToBytes(requestAndResponse.ResponsePayload);

                    Console.WriteLine("Releasing the method mutex");
                    mutex.Release();

                    Console.WriteLine("Returning the result");
                    return(new MethodResponse(responseBytes, status));
                }
            };

            Console.WriteLine("Setting the handler");
            await client.SetMethodHandlerAsync(methodName, callback, null).ConfigureAwait(false);

            Console.WriteLine("Waiting on the method mutex");
            await mutex.WaitAsync().ConfigureAwait(false);

            Console.WriteLine("Method mutex released.  Waiting for a tiny bit.");  // Otherwise, the connection might close before the response is actually sent
            await Task.Delay(100).ConfigureAwait(false);

            Console.WriteLine("Nulling the handler");
            await client.SetMethodHandlerAsync(methodName, null, null).ConfigureAwait(false);

            Console.WriteLine("RoundtripMethodCallAsync is complete");
            return(new object());
        }
Пример #36
0
        public async Task <EventBody> WaitForInputMessageAsync(string connectionId, string inputName)
        {
            Console.WriteLine("WaitForInputMessageAsync received for {0} with inputName {1}", connectionId, inputName);
            var mutex = new System.Threading.SemaphoreSlim(1);
            await mutex.WaitAsync().ConfigureAwait(false);  // Grab the mutex. The handler will release it later

            byte[]         bytes   = null;
            var            client  = objectMap[connectionId];
            MessageHandler handler = async(msg, context) =>
            {
                Console.WriteLine("message received");
                bytes = msg.GetBytes();
                await client.SetInputMessageHandlerAsync(inputName, null, null).ConfigureAwait(false);

                Console.WriteLine("releasing inputMessage mutex");
                mutex.Release();
                return(MessageResponse.Completed);
            };

            Console.WriteLine("Setting input handler");
            await client.SetInputMessageHandlerAsync(inputName, handler, null).ConfigureAwait(false);

            Console.WriteLine("Waiting for inputMessage mutex to release");
            await mutex.WaitAsync().ConfigureAwait(false);

            Console.WriteLine("mutex triggered.");

            string s = Encoding.UTF8.GetString(bytes);

            Console.WriteLine("message = {0}", s as object);
            object result;

            try
            {
                result = JsonConvert.DeserializeObject(s);
            }
            catch (JsonReaderException)
            {
                result = s;
            }
            return(new Models.EventBody
            {
                Body = result
            });
        }
Пример #37
0
        static async Task Main(string[] args)
        {
            // Create the semaphore.
            semaphore = new System.Threading.SemaphoreSlim(0, 3);
            Console.WriteLine("{0} tasks can enter the semaphore.",
                              semaphore.CurrentCount);
            Task[] tasks = new Task[5];

            // Create and start five numbered tasks.
            for (int i = 0; i <= 4; i++)
            {
                tasks[i] = Task.Run(() => {
                    // Each task begins by requesting the semaphore.
                    Console.WriteLine("Task {0} begins and waits for the semaphore.",
                                      Task.CurrentId);
                    semaphore.Wait();

                    Interlocked.Add(ref padding, 100);

                    Console.WriteLine("Task {0} enters the semaphore.", Task.CurrentId);

                    // The task just sleeps for 1+ seconds.
                    Thread.Sleep(1000 + padding);

                    Console.WriteLine("Task {0} releases the semaphore; previous count: {1}.",
                                      Task.CurrentId, semaphore.Release());
                });
            }

            // Wait for half a second, to allow all the tasks to start and block.
            Thread.Sleep(500);

            // Restore the semaphore count to its maximum value.
            Console.WriteLine("Main thread calls Release(3) --> ");
            semaphore.Release(3);
            Console.WriteLine("   {0} tasks can enter the semaphore.", semaphore.CurrentCount);
            // Main thread waits for the tasks to complete.
            await Task.WhenAll(tasks);

            Console.WriteLine("Main thread exits.");

            Console.ReadLine();
        }
Пример #38
0
        /// <summary>
        /// Constructor of SemaphoreSlim class
        /// </summary>
        /// <param name="context">Specify a context to have different contexts in different domains</param>
        /// <param name="name">Name of the new SemaphoreSlim</param>
        /// <param name="initialCount">The initial number of requests for the semaphoreSlim that can be granted concurrently.</param>
        /// <param name="maximumCount">The maximum number of requests for the semaphoreSlim that can be granted concurrently.</param>
        public SemaphoreSlim(Context.SemaphoreSlim context, string name, int initialCount, int maximumCount) : base(context)
        {
            ContextMapper = ctx => ctx ?? _defaultContext;

            if (!ContextMapper.Invoke(context).ObjectDictionary.TryGetValue(name, out var tempSemaphoreSlim))
            {
                lock (ContextMapper.Invoke(context).LockerObject)
                {
                    if (!ContextMapper.Invoke(context).ObjectDictionary.TryGetValue(name, out tempSemaphoreSlim))
                    {
                        _currentObject = new System.Threading.SemaphoreSlim(initialCount, maximumCount);
                        ContextMapper.Invoke(context).ObjectDictionary.TryAdd(name, _currentObject);
                    }
                }
            }

            if (tempSemaphoreSlim != null)
            {
                _currentObject = (System.Threading.SemaphoreSlim)tempSemaphoreSlim;
            }
        }
Пример #39
0
        public async Task <object> WaitForDesiredPropertyPatchAsync(string connectionId)
        {
            // Since there's no way to un-register for a patch, we have a global patch handler.  We keep the
            // "last desired props received" in a member varaible along with a mutex to trigger when this changes.
            // Not very cool and not very thread safe :(
            Console.WriteLine("WaitForDesiredPropertyPatchAsync received for " + connectionId);
            var client = objectMap[connectionId];
            var mutex  = new System.Threading.SemaphoreSlim(1);
            await mutex.WaitAsync().ConfigureAwait(false);  // Grab the mutex. The handler will release it later

            desiredPropMutex = mutex;

            Console.WriteLine("Waiting for patch");
            await mutex.WaitAsync().ConfigureAwait(false);

            Console.WriteLine("mutex triggered.");

            Console.WriteLine("Returning patch:");
            Console.WriteLine(JsonConvert.SerializeObject(lastDesiredProps));
            return(lastDesiredProps);
        }
Пример #40
0
 public void ScpToRemote(List <string> files, string dir_path, string dir, IVsOutputWindowPane outputWindowPane)
 {
     try
     {
         lock (lock_obj)
         {
             // ThreadHelper.ThrowIfNotOnUIThread();
             var dte = Package.GetGlobalService(typeof(DTE)) as EnvDTE80.DTE2;
             dte.Windows.Item(EnvDTE.Constants.vsWindowKindOutput).Activate();
             if (files.Count == 0)
             {
                 outputWindowPane.OutputStringThreadSafe("No file can be copied");
                 return;
             }
             ConnectionInfoStore connectionInfoStore = new ConnectionInfoStore();
             connectionInfoStore.Load();
             if (connectionInfoStore.Connections.Count < 1)
             {
                 outputWindowPane.OutputStringThreadSafe("No connection found. Add connection in [Tools] / [Options] / [Cross Platform]");
                 return;
             }
             outputWindowPane.OutputStringThreadSafe("Connecting...\n");
             if (remoteSystem == null)
             {
                 remoteSystem = new RemoteSystem((ConnectionInfo)connectionInfoStore.Connections[0]);
                 directory    = remoteSystem.FileSystem.GetDirectory(SpecialDirectory.Home);
             }
             using (var concurrencySemaphore = new System.Threading.SemaphoreSlim(8))
             {
                 int         num    = 0;
                 int         length = files.Count;
                 List <Task> tasks  = new List <Task>();
                 foreach (string file in files)
                 {
                     concurrencySemaphore.Wait();
                     var t = Task.Run(() =>
                     {
                         string str2           = file.Substring(dir_path.Length);
                         string remoteFileName = directory.FullPath + "/projects/" + dir + str2.Replace('\\', '/');
                         string remotePath     = remoteFileName.Substring(0, remoteFileName.LastIndexOf('/'));
                         try
                         {
                             if (File.Exists(file))
                             {
                                 remoteSystem.FileSystem.UploadFile(file, remoteFileName);
                                 outputWindowPane.OutputStringThreadSafe("[" + Interlocked.Increment(ref num) + "/" + length + "] " + remoteFileName + "\n");
                             }
                             else
                             {
                                 Interlocked.Increment(ref num);
                                 outputWindowPane.OutputStringThreadSafe("Skip " + file + " (file not exists)\n");
                             }
                         }
                         catch (liblinux.IO.IOException ex1)
                         {
                             if (ex1.Message.Contains("No such file"))
                             {
                                 remoteSystem.FileSystem.CreateDirectories(remotePath);
                                 remoteSystem.FileSystem.UploadFile(file, remoteFileName);
                                 outputWindowPane.OutputStringThreadSafe("[" + Interlocked.Increment(ref num) + "/" + length + "] " + remoteFileName + "\n");
                             }
                             else
                             {
                                 Interlocked.Increment(ref num);
                                 outputWindowPane.OutputStringThreadSafe("Upload failed: " + file + "\n");
                             }
                         }
                         catch (Exception ex)
                         {
                             Interlocked.Increment(ref num);
                             outputWindowPane.OutputStringThreadSafe("Upload failed: " + file + ", ex: " + ex.ToString() + "\n");
                         }
                         finally
                         {
                             concurrencySemaphore.Release();
                         }
                     });
                     tasks.Add(t);
                 }
                 Task.WaitAll(tasks.ToArray());
             }
             remoteSystem.Disconnect();
             remoteSystem.Dispose();
             outputWindowPane.OutputStringThreadSafe("Copy to " + remoteSystem.ConnectionInfo.HostNameOrAddress + " done.\n");
             // prepare for next time
             remoteSystem = new RemoteSystem((ConnectionInfo)connectionInfoStore.Connections[0]);
             directory    = remoteSystem.FileSystem.GetDirectory(SpecialDirectory.Home);
         }
     }
     catch (Exception ex)
     {
         remoteSystem = null;
         throw ex;
     }
 }
Пример #41
0
 public static async Task <T> DeserializeAsync <T>(Windows.Storage.StorageFolder folder, string fileName, System.Threading.SemaphoreSlim semaphore) where T : class
 {
     try
     {
         return(await DeserializeAsync <T>((await folder.GetItemAsync(fileName)) as Windows.Storage.StorageFile, semaphore));
     }
     catch
     {
         return(null);
     }
 }
Пример #42
0
    public static async Task SerializeAsync <T>(T content, Windows.Storage.StorageFolder folder, string fileName, System.Threading.SemaphoreSlim semaphore)
    {
        await semaphore.WaitAsync();

        try
        {
            var f = await folder.CreateFileAsync(fileName, Windows.Storage.CreationCollisionOption.ReplaceExisting);

            using var s = (await f.OpenAsync(Windows.Storage.FileAccessMode.ReadWrite)).AsStream();
            var serializer = new System.Xml.Serialization.XmlSerializer(typeof(T));
            serializer.Serialize(s, content);
        }
        catch { }
        finally
        {
            semaphore.Release();
        }
    }
Пример #43
0
        /// <summary>
        /// Creates grouping subscriptions and waits for the notification events to flow
        /// </summary>
        /// <param name="impersonationId"></param>
        /// <returns></returns>
        async public System.Threading.Tasks.Task CreateStreamingSubscriptionGroupingAsync(string impersonationId)
        {
            var database = EWSConstants.Config.Database;

            using (EWSDbContext context = new EWSDbContext(database))
            {
                var smtpAddresses = await context.RoomListRoomEntities.ToListAsync();

                foreach (var sMailbox in smtpAddresses)
                {
                    var addedBox = _mailboxes.AddMailbox(sMailbox.SmtpAddress);
                    if (!addedBox)
                    {
                        _traceListener.Trace("SyncProgram", $"Failed to add SMTP {sMailbox.SmtpAddress}");
                    }

                    MailboxInfo mailboxInfo = _mailboxes.Mailbox(sMailbox.SmtpAddress);
                    if (mailboxInfo != null)
                    {
                        GroupInfo groupInfo = null;
                        if (_groups.ContainsKey(mailboxInfo.GroupName))
                        {
                            groupInfo = _groups[mailboxInfo.GroupName];
                        }
                        else
                        {
                            groupInfo = new GroupInfo(mailboxInfo.GroupName, mailboxInfo.SMTPAddress, mailboxInfo.EwsUrl, EwsToken, _traceListener);
                            _groups.Add(mailboxInfo.GroupName, groupInfo);
                        }

                        if (groupInfo.Mailboxes.Count > 199)
                        {
                            // We already have enough mailboxes in this group, so we rename it and create a new one
                            // Renaming it means that we can still put new mailboxes into the correct group based on GroupingInformation
                            int i = 1;
                            while (_groups.ContainsKey($"{groupInfo.Name}-{i}"))
                            {
                                i++;
                            }

                            // Remove previous grouping name from stack
                            _groups.Remove(groupInfo.Name);

                            // Add the grouping back with the new grouping name [keep the GroupInfo with previous name]
                            _groups.Add($"{groupInfo.Name}-{i}", groupInfo);

                            // Provision a new GroupInfo with the GroupName
                            groupInfo = new GroupInfo(mailboxInfo.GroupName, mailboxInfo.SMTPAddress, mailboxInfo.EwsUrl, EwsToken, _traceListener);

                            // Add GroupInfo to stack
                            _groups.Add(mailboxInfo.GroupName, groupInfo);
                        }

                        // Add the mailbox to the collection
                        groupInfo.Mailboxes.Add(sMailbox.SmtpAddress);
                    }
                }

                // Enable the Grouping
                foreach (var _group in _groups)
                {
                    _traceListener.Trace("SyncProgram", $"Opening connections for {_group.Key}");

                    var groupName = _group.Key;
                    var groupInfo = _group.Value;

                    // Create a streaming connection to the service object, over which events are returned to the client.
                    // Keep the streaming connection open for 30 minutes.
                    if (AddGroupSubscriptions(context, groupName))
                    {
                        _traceListener.Trace("SyncProgram", $"{groupInfo.Mailboxes.Count()} mailboxes primed for StreamingSubscriptions.");
                    }
                    else
                    {
                        _traceListener.Trace("SyncProgram", $"Group {groupInfo.Name} failed in StreamingSubscription events.");
                    }
                }
            }

            using (var semaphore = new System.Threading.SemaphoreSlim(1))
            {
                // Block the Thread
                semaphore.Wait();

                // Establish the StreamingSubscriptionConnections based on the GroupingInfo
                foreach (var connection in _connections)
                {
                    var _group      = _groups[connection.Key];
                    var _connection = connection.Value;
                    if (_connection.IsOpen)
                    {
                        _group.IsConnectionOpen = true;
                        return;
                    }

                    try
                    {
                        _connection.Open();
                        _group.IsConnectionOpen = true;
                    }
                    catch (Exception ex)
                    {
                        _traceListener.Trace("SyncProgram", $"Error opening streamingsubscriptionconnection for group {_group.Name} MSG {ex.Message}");
                    }
                }

                // Lock the Thread Until its cancelled or fails
                await semaphore.WaitAsync(CancellationTokenSource.Token);
            }
        }
Пример #44
0
        private async Task <(int, int)> Scrape(Func <CancellationToken, Task <int> > process, System.Threading.SemaphoreSlim complete, TimeSpan interval, CancellationToken cancellation)
        {
            var success = 0;
            var error   = 0;
            var delay   = interval;

            while (!cancellation.IsCancellationRequested)
            {
                if (await complete.WaitAsync(delay, cancellation))
                {
                    complete.Release();
                    break;
                }
                try
                {
                    var start = DateTimeOffset.UtcNow;
                    await process(cancellation);

                    var elapsed = DateTimeOffset.UtcNow - start;
                    delay = elapsed > interval ? TimeSpan.Zero : (interval - elapsed);
                    ++success;
                }
                catch { ++error; }
            }

            return(success, error);
        }
Пример #45
0
        public static async Task <IDisposable> Lock(this System.Threading.SemaphoreSlim semaphore)
        {
            await semaphore.WaitAsync();

            return(new LockRelease(semaphore));
        }
Пример #46
0
 public ThrottledTaskPool(int maxConcurrentTasks)
 {
     _semaphore = new System.Threading.SemaphoreSlim(maxConcurrentTasks, maxConcurrentTasks);
 }
Пример #47
0
        public static void RunWithController(TestHelper helper, IControllerPrx controller)
        {
            Communicator?communicator = helper.Communicator;

            TestHelper.Assert(communicator != null);

            var timeout = ITimeoutPrx.Parse(helper.GetTestProxy("timeout", 0), communicator);

            System.IO.TextWriter output = helper.Output;
            output.Write("testing connect timeout... ");
            output.Flush();
            {
                Dictionary <string, string>?properties = communicator.GetProperties();
                properties["Ice.ConnectTimeout"] = "100ms";
                using var comm = new Communicator(properties);

                var to = ITimeoutPrx.Parse(helper.GetTestProxy("timeout", 0), comm);

                // Expect ConnectTimeoutException.
                controller.HoldAdapter(-1);
                try
                {
                    to.Op();
                    TestHelper.Assert(false);
                }
                catch (ConnectTimeoutException)
                {
                    // Expected.
                }
                controller.ResumeAdapter();
                timeout.Op(); // Ensure adapter is active.
            }
            {
                // Expect success.
                controller.HoldAdapter(100);
                timeout.Op();
            }
            output.WriteLine("ok");

            // The sequence needs to be large enough to fill the write/recv buffers
            byte[] seq = new byte[2000000];

            output.Write("testing connection timeout... ");
            output.Flush();
            {
                // Expect TimeoutException.
                controller.HoldAdapter(-1);
                timeout.GetConnection() !.Acm = new Acm(TimeSpan.FromMilliseconds(50),
                                                        AcmClose.OnInvocationAndIdle,
                                                        AcmHeartbeat.Off);
                try
                {
                    timeout.SendData(seq);
                    TestHelper.Assert(false);
                }
                catch (ConnectionTimeoutException)
                {
                    // Expected.
                }
                controller.ResumeAdapter();
                timeout.Op(); // Ensure adapter is active.
            }
            {
                // Expect success.
                controller.HoldAdapter(100);
                try
                {
                    timeout.SendData(new byte[1000000]);
                }
                catch (ConnectionTimeoutException)
                {
                    TestHelper.Assert(false);
                }
            }
            output.WriteLine("ok");

            output.Write("testing invocation timeout... ");
            output.Flush();
            {
                timeout.IcePing(); // Makes sure a working connection is associated with the proxy
                Connection?connection = timeout.GetConnection();
                try
                {
                    using var timeoutTokenSource = new CancellationTokenSource(TimeSpan.FromMilliseconds(100));
                    timeout.SleepAsync(1000, cancel: timeoutTokenSource.Token).Wait();
                    TestHelper.Assert(false);
                }
                catch (AggregateException ex) when(ex.InnerException is OperationCanceledException)
                {
                }
                timeout.IcePing();

                TestHelper.Assert(connection == timeout.GetConnection());
                try
                {
                    using var timeoutTokenSource = new CancellationTokenSource(TimeSpan.FromMilliseconds(1000));
                    timeout.SleepAsync(100, cancel: timeoutTokenSource.Token).Wait();
                }
                catch (AggregateException ex) when(ex.InnerException is OperationCanceledException)
                {
                    TestHelper.Assert(false);
                }
                TestHelper.Assert(connection == timeout.GetConnection());
            }
            output.WriteLine("ok");

            output.Write("testing close timeout... ");
            output.Flush();
            {
                Dictionary <string, string> properties = communicator.GetProperties();
                properties["Ice.CloseTimeout"] = "100ms";
                using var comm = new Communicator(properties);

                var to = ITimeoutPrx.Parse(helper.GetTestProxy("timeout", 0), comm);

                Connection?connection  = to.GetConnection();
                Connection?connection2 = timeout.GetConnection();  // No close timeout

                TestHelper.Assert(connection != null && connection2 != null);

                controller.HoldAdapter(-1);

                // Make sure there's no ReadAsync pending
                _ = to.IcePingAsync();
                _ = timeout.IcePingAsync();

                var semaphore = new System.Threading.SemaphoreSlim(0);
                connection.Closed += (sender, args) => semaphore.Release();
                connection.Close(ConnectionClose.Gracefully);
                TestHelper.Assert(semaphore.Wait(500));

                connection2.Closed += (sender, args) => semaphore.Release();
                connection2.Close(ConnectionClose.Gracefully);
                TestHelper.Assert(!semaphore.Wait(500));

                controller.ResumeAdapter();
                timeout.Op(); // Ensure adapter is active.
            }
            output.WriteLine("ok");

            output.Write("testing invocation timeouts with collocated calls... ");
            output.Flush();
            {
                communicator.SetProperty("TimeoutCollocated.AdapterId", "timeoutAdapter");

                ObjectAdapter adapter = communicator.CreateObjectAdapter("TimeoutCollocated");
                adapter.Activate();

                ITimeoutPrx proxy = adapter.AddWithUUID(new Timeout(), ITimeoutPrx.Factory);
                try
                {
                    using var timeoutTokenSource = new CancellationTokenSource(TimeSpan.FromMilliseconds(100));
                    proxy.SleepAsync(500, cancel: timeoutTokenSource.Token).Wait();
                    TestHelper.Assert(false);
                }
                catch (AggregateException ex) when(ex.InnerException is OperationCanceledException)
                {
                }

                adapter.Dispose();
            }
            output.WriteLine("ok");

            controller.Shutdown();
        }