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; } } }
//////////////////////////////////////////////////////////// // // 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); }
/// <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)); }
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);
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; }
void IProgress <bool> .Report(bool value) { _scheduler = TaskScheduler.Current; _event.Set(); }
/// <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); }
protected AsyncProcess(TaskScheduler?scheduler) : base(scheduler) { }
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);
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; }
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);
// 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);
/// <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()); }
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); }
public Subscription(Func <TMessage, Task> handler, TaskScheduler?scheduler = null) { Handler = handler; Scheduler = scheduler; }
public ActionTaskManagerEntry(Action action, TaskScheduler?scheduler, TaskCreationOptions options, ConcurrencyProfile concurrencyProfile = default, Delegate? @delegate = null) : base(@delegate ?? action, scheduler, options, concurrencyProfile) => Task = new Task(() =>
/// <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);