Example #1
0
        async Task Worker()
        {
            for (; ; )
            {
                WorkHandle work;

                lock (_lock)
                {
                    if (_workQueue.Count < 1)
                        return;

                    work = _workQueue.Dequeue();
                }

#if DEBUG
                _work = work;
#endif
                try
                {
                    work.TryDeregister();

                    await work.RunAsync().ConfigureAwait(false);
                }
                catch (Exception ex)
                {
                    Debug.WriteLine("AsyncFifoWorker.Worker() failed: " + ex.ExtendedMessage());
                }

#if DEBUG
                _work = null;
#endif
                work.Dispose();
            }
        }
Example #2
0
        WorkHandle PostWork(Func<Task> workFunc, bool createTcs, string description, CancellationToken cancellationToken)
        {
            if (workFunc == null)
                throw new ArgumentNullException(nameof(workFunc));

            cancellationToken.ThrowIfCancellationRequested();

            WorkHandle work;

            lock (_lock)
            {
                if (_isClosed)
                    throw new InvalidOperationException("AsyncFifoWorker is closed");

                work = new WorkHandle(workFunc, createTcs ? new TaskCompletionSource<object>() : null);

#if DEBUG
                work.Description = description;
#endif
                _workQueue.Enqueue(work);
            }

            if (!work.Register(RemoveWork, cancellationToken))
            {
                Debug.WriteLine("AsyncFifoWorker.PostWork() work already done");

                return work;
            }

            try
            {
                _signalTask.Fire();
            }
            catch (ObjectDisposedException)
            {
                RemoveWork(work);

                if (_workQueue.Count > 0)
                    Debug.WriteLine("AsyncFifoWorker.Post() object disposed but there are still {0} pending", _workQueue.Count);

                throw;
            }

            return work;
        }