示例#1
0
        private ObjectAdapter CreateObjectAdapter(
            string name,
            bool serializeDispatch,
            TaskScheduler?taskScheduler,
            IRouterPrx?router)
        {
            if (name.Length == 0)
            {
                throw new ArgumentException("the empty string is not a valid object adapter name", nameof(name));
            }

            lock (_mutex)
            {
                if (IsDisposed)
                {
                    throw new CommunicatorDisposedException();
                }
                if (_shutdownSemaphore != null)
                {
                    throw new InvalidOperationException("ShutdownAsync has been called on this communicator");
                }

                if (!_adapterNamesInUse.Add(name))
                {
                    throw new ArgumentException($"an object adapter with name `{name}' was already created",
                                                nameof(name));
                }

                try
                {
                    var adapter = new ObjectAdapter(this, name, serializeDispatch, taskScheduler, router);
                    _adapters.Add(adapter);
                    return(adapter);
                }
                catch
                {
                    _adapterNamesInUse.Remove(name);
                    throw;
                }
            }
        }
示例#2
0
        ////////////////////////////////////////////////////////////
        //
        // Internal overridable methods
        //


        /// <summary>
        /// Attempts to execute the target task synchronously.
        /// </summary>
        /// <param name="task">The task to run.</param>
        /// <param name="taskWasPreviouslyQueued">True if the task may have been previously queued,
        /// false if the task was absolutely not previously queued.</param>
        /// <returns>True if it ran, false otherwise.</returns>
        internal bool TryRunInline(Task task, bool taskWasPreviouslyQueued)
        {
            // Do not inline unstarted tasks (i.e., task.ExecutingTaskScheduler == null).
            // Do not inline TaskCompletionSource-style (a.k.a. "promise") tasks.
            // No need to attempt inlining if the task body was already run (i.e. either TASK_STATE_DELEGATE_INVOKED or TASK_STATE_CANCELED bits set)
            TaskScheduler?ets = task.ExecutingTaskScheduler;

            // Delegate cross-scheduler inlining requests to target scheduler
            if (ets != this && ets != null)
            {
                return(ets.TryRunInline(task, taskWasPreviouslyQueued));
            }

            if ((ets == null) ||
                (task.m_action == null) ||
                task.IsDelegateInvoked ||
                task.IsCanceled ||
                !RuntimeHelpers.TryEnsureSufficientExecutionStack())
            {
                return(false);
            }

            // Task class will still call into TaskScheduler.TryRunInline rather than TryExecuteTaskInline() so that
            // 1) we can adjust the return code from TryExecuteTaskInline in case a buggy custom scheduler lies to us
            // 2) we maintain a mechanism for the TLS lookup optimization that we used to have for the ConcRT scheduler (will potentially introduce the same for TP)
            if (TplEventSource.Log.IsEnabled())
            {
                task.FireTaskScheduledIfNeeded(this);
            }

            bool inlined = TryExecuteTaskInline(task, taskWasPreviouslyQueued);

            // If the custom scheduler returned true, we should either have the TASK_STATE_DELEGATE_INVOKED or TASK_STATE_CANCELED bit set
            // Otherwise the scheduler is buggy
            if (inlined && !(task.IsDelegateInvoked || task.IsCanceled))
            {
                throw new InvalidOperationException(SR.TaskScheduler_InconsistentStateAfterTryExecuteTaskInline);
            }

            return(inlined);
        }
示例#3
0
        /// <summary>Creates a new nameless object adapter. Such an object adapter has no configuration and can be
        /// associated with a bidirectional connection.</summary>
        /// <param name="serializeDispatch">Indicates whether or not this object adapter serializes the dispatching of
        /// of requests received over the same connection.</param>
        /// <param name="taskScheduler">The optional task scheduler to use for dispatching requests.</param>
        /// <param name="protocol">The protocol used for this object adapter.</param>
        /// <returns>The new object adapter.</returns>
        public ObjectAdapter CreateObjectAdapter(
            bool serializeDispatch      = false,
            TaskScheduler?taskScheduler = null,
            Protocol protocol           = Protocol.Ice2)
        {
            lock (_mutex)
            {
                if (IsDisposed)
                {
                    throw new CommunicatorDisposedException();
                }
                if (_shutdownTask != null)
                {
                    throw new InvalidOperationException("ShutdownAsync has been called on this communicator");
                }

                var adapter = new ObjectAdapter(this, serializeDispatch, taskScheduler, protocol);
                _adapters.Add(adapter);
                return(adapter);
            }
        }
        /// <summary>Creates a new object adapter with the specified router proxy. Calling this method is equivalent
        /// to setting the name.Router property and then calling
        /// <see cref="CreateObjectAdapter(string, bool, TaskScheduler?)"/>.</summary>
        /// <param name="name">The object adapter name. Cannot be empty.</param>
        /// <param name="router">The proxy to the router.</param>
        /// <param name="serializeDispatch">Indicates whether or not this object adapter serializes the dispatching of
        /// of requests received over the same connection.</param>
        /// <param name="taskScheduler">The optional task scheduler to use for dispatching requests.</param>
        /// <returns>The new object adapter.</returns>
        public ObjectAdapter CreateObjectAdapterWithRouter(
            string name,
            IRouterPrx router,
            bool serializeDispatch      = false,
            TaskScheduler?taskScheduler = null)
        {
            if (name.Length == 0)
            {
                throw new ArgumentException("the empty string is not a valid object adapter name", nameof(name));
            }

            // We set the proxy properties here, although we still use the proxy supplied.
            Dictionary <string, string> properties = router.ToProperty($"{name}.Router");

            foreach (KeyValuePair <string, string> entry in properties)
            {
                SetProperty(entry.Key, entry.Value);
            }

            return(AddObjectAdapter(name, serializeDispatch, taskScheduler, router));
        }
示例#5
0
        public EnumerableSourceCore(ISourceBlock <T> parent, Action enumerate, TaskScheduler?taskScheduler, CancellationToken cancellationToken)
        {
            this._parent            = parent;
            this._cancellationToken = cancellationToken;

            if (taskScheduler == null || taskScheduler == TaskScheduler.Default)
            {
#if THREADPOOL
                WaitCallback enumerateCb = x => ((Action)x).Invoke();
                this._enumerate = () => ThreadPool.QueueUserWorkItem(enumerateCb, enumerate);

                WaitCallback offerCb = x => ((EnumerableSourceCore <T>)x).OfferToTargets();
                this._offerToTargetsOnTaskScheduler = () => ThreadPool.QueueUserWorkItem(offerCb, this);
#else
                this._enumerate = () => Task.Run(enumerate);

                Action offerAction = this.OfferToTargets;
                this._offerToTargetsOnTaskScheduler = () => Task.Run(offerAction);
#endif
            }
            else
            {
                var taskFactory = new TaskFactory(taskScheduler);
                this._enumerate = () => taskFactory.StartNew(enumerate);

                Action offerAction = this.OfferToTargets;
                this._offerToTargetsOnTaskScheduler = () => taskFactory.StartNew(offerAction);
            }

            if (cancellationToken.IsCancellationRequested)
            {
                this.State = StateEnum.Completed;
                this._completeRequested = true;
                this._tcs.TrySetCanceled(cancellationToken);
            }
            else if (cancellationToken.CanBeCanceled)
            {
                this._cancelReg = cancellationToken.Register(() => this.Complete(false));
            }
        }
        public void Start(TimeSpan delay, TaskScheduler?scheduler = null)
        {
            if (delay < TimeSpan.Zero)
            {
                RunSynchronously();
            }
            else if (delay == TimeSpan.Zero)
            {
                if (scheduler is null)
                {
                    Start();
                }
                else
                {
                    Start(scheduler);
                }
            }
            else
            {
                var runState = 0;

                ContinueWith(t =>
                {
                    // If this is arbitrarily run before the delay, then cancel the delay.
                    if (Interlocked.Increment(ref runState) < 2)
                    {
                        Cancel();
                    }
                });

                Delay(delay, TokenSource !.Token)
                .OnFullfilled(() =>
                {
                    Interlocked.Increment(ref runState);
                    this.EnsureStarted(scheduler);
                });
            }
        }
    public static async Task <IReadOnlyCollection <T> > WhenAllParallelAsync <T>(IAsyncEnumerable <T> source,
                                                                                 Func <T, CancellationToken, Task <T> > action,
                                                                                 CancellationToken token,
                                                                                 int?maxDegreeOfParallelism = default,
                                                                                 TaskScheduler?scheduler    = null)
    {
        var results = new ConcurrentBag <T>();

        var options = new ExecutionDataflowBlockOptions
        {
            MaxDegreeOfParallelism = maxDegreeOfParallelism ?? DataflowBlockOptions.Unbounded
        };

        if (scheduler is not null)
        {
            options.TaskScheduler = scheduler;
        }

        async Task AwaitItem(T item)
        {
            T result = await action(item, token);

            results.Add(result);
        }

        var block = new ActionBlock <T>(AwaitItem, options);

        await foreach (T item in source.WithCancellation(token))
        {
            block.Post(item);
        }

        block.Complete();
        await block.Completion;

        return(results);
    }
        public static CancellableTask StartNew(Action <CancellationToken> action, TimeSpan?delay = null, TaskScheduler?scheduler = default)
        {
            var ts    = new CancellationTokenSource();
            var token = ts.Token;
            var task  = new CancellableTask(() => action(token), token)
            {
                TokenSource = ts
            };

            task.Start(delay ?? TimeSpan.Zero, scheduler);
            return(task);
        }
 public static CancellableTask StartNew(Action action, TimeSpan?delay = null, TaskScheduler?scheduler = default)
 => StartNew(delay ?? TimeSpan.Zero, action, scheduler);
 public void Start(int millisecondsDelay, TaskScheduler?scheduler = default)
 => Start(TimeSpan.FromMilliseconds(millisecondsDelay), scheduler);
示例#11
0
 public AsyncEnumerableSourceBlock(IAsyncEnumerable <T> enumerable, TaskScheduler?taskScheduler, CancellationToken cancellationToken)
 {
     this._core              = new EnumerableSourceCore <T>(this, this.Enumerate, taskScheduler, cancellationToken);
     this._enumerable        = enumerable;
     this._cancellationToken = cancellationToken;
 }
示例#12
0
文件: AllTests.cs 项目: rtxlab/ice
 void IProgress <bool> .Report(bool value)
 {
     _scheduler = TaskScheduler.Current;
     _event.Set();
 }
示例#13
0
        /// <summary>
        /// Invokes synchronous delegate asynchronously.
        /// </summary>
        /// <param name="action">The action to invoke asynchronously.</param>
        /// <param name="state">The state object to be passed to the action.</param>
        /// <param name="callback">The callback to be invoked on completion.</param>
        /// <param name="options">The task scheduling options.</param>
        /// <param name="scheduler">The task scheduler.</param>
        /// <returns>The task representing asynchronous execution of the action.</returns>
        public static Task BeginInvoke(this Action <object?> action, object?state, AsyncCallback?callback, TaskCreationOptions options = TaskCreationOptions.None, TaskScheduler?scheduler = null)
        {
            var task = Task.Factory.StartNew(action, state, CancellationToken.None, options, scheduler ?? TaskScheduler.Default);

            if (callback != null)
            {
                task.OnCompleted(callback);
            }

            return(task);
        }
示例#14
0
 protected AsyncProcess(TaskScheduler?scheduler) : base(scheduler)
 {
 }
示例#15
0
 public FuncTaskManagerEntry(Func <TResult> func, TaskScheduler?scheduler, TaskCreationOptions options, ConcurrencyProfile concurrencyProfile = default, Delegate? @delegate = null) : base(@delegate ?? func, scheduler, options, concurrencyProfile) => Task = new Task <TResult>(() =>
 /// <summary>Creates a new object adapter with the specified endpoint string. This method generates a UUID for
 /// the object adapter name and then calls
 /// <see cref="CreateObjectAdapterWithEndpoints(string, string, bool, TaskScheduler?)"/>.</summary>
 /// <param name="endpoints">The endpoint string for the object adapter.</param>
 /// <param name="serializeDispatch">Indicates whether or not this object adapter serializes the dispatching of
 /// of requests received over the same connection.</param>
 /// <param name="taskScheduler">The optional task scheduler to use for dispatching requests.</param>
 /// <returns>The new object adapter.</returns>
 public ObjectAdapter CreateObjectAdapterWithEndpoints(
     string endpoints,
     bool serializeDispatch      = false,
     TaskScheduler?taskScheduler = null) =>
 CreateObjectAdapterWithEndpoints(Guid.NewGuid().ToString(), endpoints, serializeDispatch, taskScheduler);
        /// <summary>Creates a new object adapter with the specified endpoint string. Calling this method is equivalent
        /// to setting the name.Endpoints property and then calling
        /// <see cref="CreateObjectAdapter(string, bool, TaskScheduler?)"/>.</summary>
        /// <param name="name">The object adapter name. Cannot be empty.</param>
        /// <param name="endpoints">The endpoint string for the object adapter.</param>
        /// <param name="serializeDispatch">Indicates whether or not this object adapter serializes the dispatching of
        /// of requests received over the same connection.</param>
        /// <param name="taskScheduler">The optional task scheduler to use for dispatching requests.</param>
        /// <returns>The new object adapter.</returns>
        public ObjectAdapter CreateObjectAdapterWithEndpoints(string name, string endpoints,
                                                              bool serializeDispatch = false, TaskScheduler?taskScheduler = null)
        {
            if (name.Length == 0)
            {
                throw new ArgumentException("the empty string is not a valid object adapter name", nameof(name));
            }

            SetProperty($"{name}.Endpoints", endpoints);
            return(AddObjectAdapter(name, serializeDispatch, taskScheduler));
        }
 /// <summary>Creates a new nameless object adapter. Such an object adapter has no configuration and can be
 /// associated with a bi-directional connection.</summary>
 /// <param name="serializeDispatch">Indicates whether or not this object adapter serializes the dispatching of
 /// of requests received over the same connection.</param>
 /// <param name="taskScheduler">The optional task scheduler to use for dispatching requests.</param>
 /// <returns>The new object adapter.</returns>
 public ObjectAdapter CreateObjectAdapter(
     bool serializeDispatch      = false,
     TaskScheduler?taskScheduler = null) =>
 AddObjectAdapter(serializeDispatch: serializeDispatch, taskScheduler: taskScheduler);
示例#19
0
        public AsyncTransformQueue(Func <TInput, CancellationToken, Task <TOutput> > transform, int capacity, TaskScheduler?scheduler)
        {
            Contract.NotNull(transform);
            if (capacity <= 0)
            {
                throw new ArgumentOutOfRangeException(nameof(capacity), "Capacity must be greater than zero");
            }

            m_transform = transform;
            m_capacity  = capacity;
            m_scheduler = scheduler ?? TaskScheduler.Default;
        }
 public TaskSchedulerAutoResetEvent(bool initialState, TaskScheduler?taskScheduler)
 {
     this._signaled      = initialState;
     this._taskScheduler = taskScheduler ?? TaskScheduler.Default;
 }
示例#21
0
 protected AsyncProcess(TaskScheduler?scheduler) => Scheduler = scheduler ?? TaskScheduler.Default;
 /// <summary>Creates a new object adapter with the specified router proxy. This method generates a UUID for
 /// the object adapter name and then calls
 /// <see cref="CreateObjectAdapterWithRouter(string, IRouterPrx, bool, TaskScheduler?)"/>.</summary>
 /// <param name="router">The proxy to the router.</param>
 /// <param name="serializeDispatch">Indicates whether or not this object adapter serializes the dispatching of
 /// of requests received over the same connection.</param>
 /// <param name="taskScheduler">The optional task scheduler to use for dispatching requests.</param>
 /// <returns>The new object adapter.</returns>
 public ObjectAdapter CreateObjectAdapterWithRouter(
     IRouterPrx router,
     bool serializeDispatch      = false,
     TaskScheduler?taskScheduler = null) =>
 CreateObjectAdapterWithRouter(Guid.NewGuid().ToString(), router, serializeDispatch, taskScheduler);
示例#23
0
 // ReSharper disable once MemberCanBeProtected.Global
 public AsyncProcess(Action <Progress> closure, TaskScheduler?scheduler = null)
     : base(closure, scheduler)
 {
 }
 /// <summary>Creates a new object adapter. The communicator uses the object adapter's name to lookup its
 /// properties, such as name.Endpoints.</summary>
 /// <param name="name">The object adapter name. Cannot be empty.</param>
 /// <param name="serializeDispatch">Indicates whether or not this object adapter serializes the dispatching of
 /// of requests received over the same connection.</param>
 /// <param name="taskScheduler">The optional task scheduler to use for dispatching requests.</param>
 /// <returns>The new object adapter.</returns>
 public ObjectAdapter CreateObjectAdapter(
     string name,
     bool serializeDispatch      = false,
     TaskScheduler?taskScheduler = null) =>
 AddObjectAdapter(name, serializeDispatch, taskScheduler);
示例#25
0
        /// <summary>
        /// Invokes synchronous delegate asynchronously.
        /// </summary>
        /// <typeparam name="TResult">The type of result of asynchronous operation.</typeparam>
        /// <param name="function">The function to invoke asynchronously.</param>
        /// <param name="state">The state object to be passed to the action.</param>
        /// <param name="callback">The callback to be invoked on completion.</param>
        /// <param name="options">The task scheduling options.</param>
        /// <param name="scheduler">The task scheduler.</param>
        /// <param name="token">The token that can be used to cancel the operation.</param>
        /// <returns>The task representing asynchronous execution of the action.</returns>
        public static Task <TResult> BeginInvoke <TResult>(this Func <object?, CancellationToken, TResult> function, object?state, AsyncCallback?callback, TaskCreationOptions options = TaskCreationOptions.None, TaskScheduler?scheduler = null, CancellationToken token = default)
        {
            var task = Task <TResult> .Factory.StartNew(s => function(s, token), state, token, options, scheduler ?? TaskScheduler.Default);

            if (callback != null)
            {
                task.OnCompleted(callback);
            }

            return(task);
        }
        /// <summary>
        ///     Executes the delegate continuously until cancelled by the subscriber.
        ///     <remarks>
        ///         It's important to add an additional buffer or window to this to avoid busy waiting, or use the built-in
        ///         interval.
        ///     </remarks>
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="delegate"></param>
        /// <param name="interval"></param>
        /// <param name="scheduler"></param>
        /// <returns></returns>
        public static IObservable <T> AsContinuousObservable <T>(this Func <IEnumerable <T> > @delegate,
                                                                 TimeSpan?interval = null, TaskScheduler?scheduler = default)
        {
            scheduler ??= TaskScheduler.Default;

            if (interval.HasValue)
            {
                return(Observable.Create <T>((observer, cancellationToken) => scheduler.Run(async() =>
                {
                    await Task.Delay(interval.Value, cancellationToken);

                    if (!cancellationToken.IsCancellationRequested)
                    {
                        var items = @delegate();
                        foreach (var item in items)
                        {
                            observer.OnNext(item);
                        }
                    }

                    cancellationToken.ThrowIfCancellationRequested();
                }, cancellationToken)).Repeat());
            }

            return(Observable.Create <T>((observer, cancelToken) => scheduler.Run(() =>
            {
                if (!cancelToken.IsCancellationRequested)
                {
                    var items = @delegate();
                    foreach (var item in items)
                    {
                        observer.OnNext(item);
                    }
                }

                cancelToken.ThrowIfCancellationRequested();
            }, cancelToken)).Repeat());
        }
示例#27
0
文件: AllTests.cs 项目: rtxlab/ice
        public static async ValueTask AllTestsWithServer(TestHelper helper, bool collocated, int server)
        {
            System.IO.TextWriter output = helper.Output;

            TaskScheduler?scheduler = TaskScheduler.Current;

            var proxy = ITestIntfPrx.Parse(helper.GetTestProxy("test", server), helper.Communicator !);

            if (collocated)
            {
                // With collocation, synchronous calls dispatched on an object adapter which doesn't set a task
                // scheduler are dispatched from the client invocation task scheduler.
                var context = new Dictionary <string, string>()
                {
                    { "scheduler", scheduler.Id.ToString() }
                };
                proxy.PingSync(context);
                proxy.Ping(context);
            }
            else
            {
                proxy.PingSync();
                proxy.Ping();
            }

            // Ensure the continuation is ran on the current task scheduler
            await proxy.PingSyncAsync();

            TestHelper.Assert(TaskScheduler.Current == scheduler);
            await proxy.PingAsync();

            TestHelper.Assert(TaskScheduler.Current == scheduler);

            // The continuation set with ContinueWith are expected to be ran on the Current task
            // scheduler if no task scheduler is provided to ContinueWith.
            Func <string, Action <Task> > checkScheduler = (op) =>
            {
                return(t =>
                {
                    if (TaskScheduler.Current != scheduler)
                    {
                        throw new TestFailedException(
                            $"unexpected scheduler for {op} ContinueWith {TaskScheduler.Current}");
                    }
                });
            };
            await proxy.PingSyncAsync().ContinueWith(checkScheduler("pingSyncAsync"), TaskScheduler.Current);

            TestHelper.Assert(TaskScheduler.Current == scheduler);
            await proxy.PingAsync().ContinueWith(checkScheduler("pingAsyncAsync"), TaskScheduler.Current);

            TestHelper.Assert(TaskScheduler.Current == scheduler);

            // The progress Report callback is always called from the default task scheduler right now.
            Progress progress;

            progress = new Progress();
            await proxy.PingSyncAsync(progress : progress);

            TestHelper.Assert(progress.Scheduler == TaskScheduler.Default);
            progress = new Progress();
            await proxy.PingAsync(progress : progress);

            TestHelper.Assert(progress.Scheduler == TaskScheduler.Default);

            // The continuation of an awaitable setup with ConfigureAwait(false) is ran with the default
            // scheduler unless it completes synchronously in which cause it will run on the current
            // scheduler.
            await proxy.PingSyncAsync().ConfigureAwait(false);

            TestHelper.Assert(TaskScheduler.Current == TaskScheduler.Default);
            await proxy.PingAsync().ConfigureAwait(false);

            TestHelper.Assert(TaskScheduler.Current == TaskScheduler.Default);
        }
示例#28
0
 public Subscription(Func <TMessage, Task> handler, TaskScheduler?scheduler = null)
 {
     Handler   = handler;
     Scheduler = scheduler;
 }
示例#29
0
 public ActionTaskManagerEntry(Action action, TaskScheduler?scheduler, TaskCreationOptions options, ConcurrencyProfile concurrencyProfile = default, Delegate? @delegate = null) : base(@delegate ?? action, scheduler, options, concurrencyProfile) => Task = new Task(() =>
示例#30
0
 /// <summary>
 /// Creates a new instance of <see cref="Subscription{TMessage}"/>
 /// </summary>
 /// <param name="handler">The message handler.</param>
 /// <param name="scheduler">The task scheduler.</param>
 /// <returns>A new instance of <see cref="Subscription{TMessage}"/></returns>
 public static Subscription <TMessage> From(Func <TMessage, Task> handler, TaskScheduler?scheduler = null)
 => new Subscription <TMessage>(handler, scheduler);