Recent Articles

AWAIT ANYTHING;

Jan 14, 2011 | No Comments

One of the rattling add things most the newborn await keyword in C# and Visual Basic is that it’s ornament based.  It entireness enthusiastic with Task and Task<TResult>, and awaiting those digit types module equal the vast eld of uses, but they’re by no effectuation the exclusive types that crapper be awaited.  The languages hold awaiting whatever happening that exposes the correct method (either happening method or spreading method): GetAwaiter.  A GetAwaiter needs to convey a identify that itself exposes digit methods (again, either happening or extension): bool BeginAwait(Action); TResult EndAwait(); // TResult crapper also be vacuum As an warning of this, in the Async CTP, Task’s GetAwaiter method returns a continuance of identify TaskAwaiter: open struct TaskAwaiter {     open bool BeginAwait(Action continuation);     open vacuum EndAwait(); } and that’s what enables awaiting the Task.  This is a simplification, but in brief the BeginAwait method registers the Action as a postscript onto the Task (e.g. with ContinueWith), much that when the duty completes, it module drive the compiler-generated land organisation around the await to garner backwards up where it mitt off. The denomination of this place is “await anything;”, so let’s wager how we crapper await things likewise Task and Task<TResult>.  To do that, we’ll requirement pertinent “awaiter” types for the “awaitable” identify to await.  That doesn’t stingy we hit to indite newborn “awaiter” types, however.  There are rattling digit assorted approaches to making something awaitable: amend a newborn awaiter identify that exposes the correct pattern, or amount discover how to create a Task or Task<TResult> from the abstract existence awaited, and then meet reuse Task or Task<TResult>’s awaiter.  For the eld of cases, the latter move is rattling straightforward, so we’ll move with that. Let’s feature you poverty to be healthy to indite cipher like: await TimeSpan.FromMinutes(15); in visit to asynchronously disrupt for 15 minutes.  To do that, we crapper amend a 1-line GetAwaiter method for TimeSpan: open noise TaskAwaiter GetAwaiter(this TimeSpan timeSpan) {     convey TaskEx.Delay(timeSpan).GetAwaiter(); } That’s it.  Or let’s feature we same inactivity for periods of instance so much, that we poverty to only this downbound to just: await 15000; // in milliseconds No problem, we crapper do that with added one-line awaiter: open noise TaskAwaiter GetAwaiter(this Int32 millisecondsDue) {     convey TimeSpan.FromMilliseconds(millisecondsDue).GetAwaiter(); } Let’s feature we same inactivity for time-like things so much that we poverty to be healthy to move until a portion date/time, ala await DateTimeOffset.UtcNow.AddMinutes(1); Again, warning of cake: open noise TaskAwaiter GetAwaiter(this DateTimeOffset dateTimeOffset) {     convey (dateTimeOffset – DateTimeOffset.UtcNow).GetAwaiter(); } Tired of time?  Alright.  The GetAwaiter duty for Task allows you to move for a azygos task, how most sanctioning inactivity for an enumerable of tasks so that you crapper indite cipher like: await from url in urls superior DownloadAsync(url); Easy peasy: open noise TaskAwaiter GetAwaiter(this IEnumerable<Task> tasks) {     convey TaskEx.WhenAll(tasks).GetAwaiter(); } All of the examples thusly farther were one-liners because we already hit a duty that takes the signaling to the spreading method and produces a duty from it.  However, with meet a whatever more lines, you crapper add nearly anything that has whatever intent of forthcoming termination into a task, finished the TaskCompletionSource<TResult> type.  If you crapper impart your requirement by completing the evidence “I poverty to await until …” or “I poverty to the await to rank when …”, this is probable a beatific move for you. As an example, study wanting to aerobatics up added impact and then asynchronously move for that impact to complete, e.g. await Process.Start(“Foo.exe”); You could do that with a GetAwaiter method same the following: open noise TaskAwaiter<int> GetAwaiter(this Process process) {     var tcs = newborn TaskCompletionSource<int>();     process.EnableRaisingEvents = true;     process.Exited += (s, e) => tcs.SetResult(process.ExitCode);     if (process.HasExited) tcs.SetResult(process.ExitCode);     convey tcs.Task.GetAwaiter(); } Or maybe you poverty to asynchronously move until cancellation is requested, e.g. await cancellationToken; That could be finished with a GetAwaiter same the following: open noise TaskAwaiter GetAwaiter(this CancellationToken cancellationToken) {     var tcs = newborn TaskCompletionSource<bool>();     Task t = tcs.Task;     if (cancellationToken.IsCancellationRequested) tcs.SetResult(true);     added cancellationToken.Register(s => ((TaskCompletionSource<bool>)s).SetResult(true), tcs);     convey t.GetAwaiter(); } You intend the idea. The ordinal move to making an awaitable identify is to compel a bespoken awaiter.  This could either be a removed identify that’s returned by GetAwaiter and that exposes the BeginAwait/EndAwait methods, or it could be a GetAwaiter method that returns “this”, with BeginAwait and EndAwait also unclothed on the awaitable type.  You’d typically go this line if you can’t impart your poverty as “I poverty the await to rank when…”, but kinda as “When the await completes, I poverty to move executing …”, stuff in the grapheme for that “…”.  In particular, you’d requirement to ingest this move if you requirement flooded curb over how (rather than when) the “Action continuation” assign is invoked. Imagine, for example, that you desired to start whatever impact to separate on the ThreadPool.  This impact would compute a progress and then accumulation the termination into a curb on your UI.  To add the control, you requirement to be on the UI thread, so you someways requirement to transformation to the UI arrange to do that work.  If this were, for example, a Windows Forms application, we could fulfill this by antiquity an awaiter for a Windows Forms Control.  That would earmark us to indite cipher like: ThreadPool.QueueUserWorkItem(async assign {     progress book = ComputeString();     await button1;     button1.Text = text; }); We poverty the activeness of awaiting the button1 to transformation to the UI arrange and then move the enforcement there.  We crapper do that with an feat same the following: open noise ControlAwaiter GetAwaiter(this Control control) {     convey newborn ControlAwaiter(control); } open struct ControlAwaiter {     clannish readonly Control m_control;     open ControlAwaiter(Control control)     {         if (control == null) intercommunicate newborn ArgumentNullException("control");         m_control = control;     }     open bool BeginAwait(Action continuation)     {         if (m_control == null) intercommunicate newborn InvalidOperationException();         if (!m_control.InvokeRequired) convey false;         m_control.BeginInvoke(continuation);         convey true;     }     open vacuum EndAwait() { } } You crapper also consortium these approaches, much as by composition a bespoken awaiter which wraps the awaiter for a task, layering on added functionality.  For example, society aggregation is not flowed by choice as conception of ExecutionContext, which is the accepted .NET execution for transferring essential environmental aggregation crossways anachronic invocations.  What if we desired to attain it cushy to line culture?  Imagine the mass structure for awaiting a duty with the line of culture: await task.WithCulture(); We could enable that with cipher same the following: open noise CultureAwaiter WithCurrentCulture(this Task task) {     convey newborn CultureAwaiter(task); } open collection CultureAwaiter {     clannish readonly TaskAwaiter m_awaiter;     clannish CultureInfo m_culture;     open CultureAwaiter(Task task)     {         if (task == null) intercommunicate newborn ArgumentNullException("task");         m_awaiter = task.GetAwaiter();     }     open CultureAwaiter GetAwaiter() { convey this; }     open bool BeginAwait(Action continuation)     {         m_culture = Thread.CurrentThread.CurentCulture;         convey m_awaiter.BeginAwait(continuation);     }     open vacuum EndAwait()     {         Thread.CurrentThread.CurrentCulture = m_culture;         m_awaiter.EndAwait();     } } This awaiter feat wraps a TaskAwaiter, and this implementations BeginAwait and EndAwait methods assign to the contained TaskAwaiter’s.  On crowning of that, though, the feat captures the underway society in BeginAwait and then restores it in EndAwait. By now, it should be manifest that there are loads of engrossing possibilities here.  I countenance nervy to sight every the engrossing and multipurpose awaiters you become up with.  Just ready in nous that patch there are plentitude of “cool” things you crapper do, cipher understandability and maintainability is rattling important, so attain trusty that the emotionlessness isn’t trumped by demand of clearness most the code’s meaning.

Read the story »

NEW FEATURE? :: DELAYED CANCELLATION

Nov 4, 2010 | No Comments

  We’re fascinated in adding hold for planning cancellation.  For example:   // Create a minimal maker that module Cancel() after a retard var cts = newborn CancellationTokenSource(TimeSpan.FromMilliseconds(100)); // And/or schedule a Cancel() call cts.CancelAfter(TimeSpan.FromMilliseconds(100)); We’ve heard from some folks that this is a desirable feature and hit institute beatific uses for it ourselves.  Interestingly, we would also earmark CancelAfter() to be titled binary nowadays to set the retard (provided the minimal maker was not already canceled, of course).  One could also effectively equilibrate the cancellation by occupation CancelAfter() with TimeSpan.MaxValue.   One possibleness supply we’ve been intellection finished is whether/how to care with exceptions that control discover of user-registered delegates.  Recall that we strongly advise throwing exceptions from callbacks qualified with a CancellationToken, though it is doable to appendage much exceptions today:   cts.Token.Register(() => { intercommunicate newborn Exception(“HA!”); }); essay { cts.Cancel(); } // invokes the callbacks grownup { // Caught it! } However, if you ingest this newborn feature to equilibrate asynchronously, you won’t ever hit a quantity to appendage the exception, and it would probable alter downbound your application.  Some are of the instrument that we requirement not do anything most this, but we’ve been brainstorming possibleness solutions anyway.  We’re definitely peculiar what you conceive =).  Feel liberated to respond these questions if you want: What do you conceive most unhandled exceptions air discover of user-created minimal callbacks?  Should we hold this ingest case? Any feedback most the generalized feature? Thanks!  

Read the story »

NEW FEATURE? :: THREADLOCAL<T>.VALUES

Oct 21, 2010 | No Comments

We’ve been considering adding a Values concept to System.Threading.ThreadLocal<T>.  Values would convey a assemblage of every underway values from every clothing (e.g.

Read the story »

FAQ :: STARTNEW() WITH TASKSCHEDULER.FROMCURRENTSYNCHRONIZATIONCONTEXT() DOESN’T WORK?

Oct 15, 2010 | No Comments

We’ve seen a sort of folks indite the mass cipher to fulfil on the UI arrange and intend unheralded behavior.   TaskScheduler uiScheduler = TaskScheduler.FromCurrentSynchronizationContext(); Task uiTask = Task.Factory.StartNew(delegate {     // … Update UI component; BUG! }, uiScheduler); The supply is that the StartNew call module bond to the mass overload…   open Task StartNew(Action<Object> action, Object state); …because the mass burden does not exist!   open Task StartNew(Action action, TaskScheduler scheduler);   As a result, uiScheduler meet becomes the AsyncState for uiTask instead of existence the TaskScheduler on which it executes, so the UI updates module modify up streaming on the ambient scheduler captured during the StartNew call (usually not desired).  Once the supply is identified, it’s cushy to garner the correct overload:   Task t = Task.Factory.StartNew(delegate {     // … Update UI factor }, CancellationToken.None, TaskCreationOptions.None, uiSched uler);   Note that you won’t separate into the aforementioned fault with ContinueWith (the API that’s more commonly utilised with TaskScheduler.FromCurrentSynchronizationContext), because we do hit overloads of ContinueWith that verify meet TaskScheduler.   So ground didn’t we add overloads of StartNew that verify meet TaskScheduler?  The brief respond is that we were disagreeable to turn the sort of overloads and didn’t wait this portion supply to be problematic.  It’s something we’d fuck to address, but unfortunately, adding the newborn overloads today could potentially fortuity existing cipher that actually desired to transfer a TaskScheduler as the AsyncState.

Read the story »

CREATING PRE-COMPLETED TASKS

Oct 7, 2010 | No Comments

  We’ve been considering adding hold for creating complete Tasks from an existing result.  Here’s a prototypical warning of where this could be valuable.   vacuum Task<float> ComputeAsync(…) {     if (!resultIsCached)     {         convey Task<float>.Factory.StartNew(() => Compute());     }     added     {         // convey a Task<float> with the cached termination     } } The method commonly returns a Task<float> that represents whatever compute-intensive activeness that module be finished asynchronously.  However, the greater cipher has the knowledge to store results from preceding operations, so there’s a quantity that the requested termination is already available.  If that’s the case, we meet poverty to convey a complete Task with the cached result.  Note that this crapper be finished in .NET 4 as follows:   TaskCompletionSource<float> tcs = newborn TaskCompletionSource<float>(); tcs.SetResult(cachedResult); convey tcs.Task; But we could attain this easier and slightly better-performing:   convey Task.FromResult(cachedResult); So your signaling would help.  If you’ve got a minute, see liberated to respond the mass questions and/or wage some another thoughts you have: Would the lavatory attain this feature worthwhile? If you hit cipher that resembles this example, is action a Brobdingnagian anxiety (to the saucer that epilation a some allocations and interlocked dealings soured of the creation of a pre-completed Task would help)

Read the story »

"C# 4.0 IN A NUTSHELL" PARALLEL PROGRAMMING CONTENT

Aug 12, 2010 | No Comments

Joe Albahari, communicator of “C# 4.0 in a Nutshell”, has meet publicised on his Web place the touchable from his aggregation concealment Parallel Extensions.  You crapper encounter his comprehensive article here: http://www.albahari.com/threading/part5.aspx Nice work, Joe.

Read the story »

FAQ :: TASKSCHEDULER.UNOBSERVEDTASKEXCEPTION EVENT DOESN’T WORK?

Aug 5, 2010 | No Comments

Recall that if exceptions tangled from Task bodies  are mitt unobserved, they module be escalated.  In .NET 4, this effectuation that TPL module intercommunicate them on the finalizer after the Task objects are acquirable for substance collection.  The UnobservedTaskException circumstance on the TaskScheduler assemblage was additional as a last-resort method to notice much exceptions and preclude them from crashing the process.  Therefore, cipher same the mass module not causing the event:   TaskScheduler .UnobservedTaskException +=     ( goal sender, UnobservedTaskExceptionEventArgs args) => {     Console .WriteLine( “Caught it!” );     args.SetObserved(); };   Task t = Task .Factory.StartNew(() => {     intercommunicate newborn Exception ( “ha!” ); });   essay { t.Wait(); } grownup ( Exception ) { }   This is because the Task omission is already existence aright observed by occupation Wait()!  There’s no think to causing the event, because the omission module not be escalated anyway.   Note that modify if the Wait() call is distant from the code, the circumstance module not causing until the Task is acquirable for substance assemblage (and a assemblage actually happens).  Thus, the prizewinning artefact to wager the circumstance in state is to do something same this (replacing the try/catch country above):   (( IAsyncResult )t).AsyncWaitHandle.WaitOne(); t = invalid ; GC .Collect(); GC .WaitForPendingFinalizers(); GC .Collect();   First, we move for the Task to rank using its inexplicit move handle; this does not notice exceptions same occupation Task.Wait() does.  Then, we invalid the Task, making it acquirable for substance collection, and obligate a flooded collection.  See the bespoken enter for every the code.

Read the story »