﻿<?xml version="1.0" encoding="utf-8"?><rss version="2.0"><channel><title>Ayende @ Rahien</title><link>http://ayende.com</link><description>Ayende @ Rahien</description><copyright>Copyright (C) Ayende Rahien  2004 - 2021 (c) 2026</copyright><ttl>60</ttl><item><title>Whut commented on TPL: Composing tasks</title><description>I'm definitely missing something, but why don't you just put CreateServerConnection and HandShakeWithServer inside one task?
</description><link>http://ayende.com/4692/tpl-composing-tasks#comment12</link><guid>http://ayende.com/4692/tpl-composing-tasks#comment12</guid><pubDate>Mon, 22 Nov 2010 10:11:31 GMT</pubDate></item><item><title>David Hanson commented on TPL: Composing tasks</title><description>I "Subscribe" ;-) to the Rx approach. 
  
  
We use the approach outlined by Omar to load data from mutliple domains services in Ria and works very well. 
  
</description><link>http://ayende.com/4692/tpl-composing-tasks#comment11</link><guid>http://ayende.com/4692/tpl-composing-tasks#comment11</guid><pubDate>Fri, 19 Nov 2010 06:19:14 GMT</pubDate></item><item><title>Jonas commented on TPL: Composing tasks</title><description>Use a TaskCompletionSource and set up your method to return you tc.Task and then wrap your async methods neatly to call tc.TrySetException | TrySetResult when they complete.. 
  
  
Tada...
</description><link>http://ayende.com/4692/tpl-composing-tasks#comment10</link><guid>http://ayende.com/4692/tpl-composing-tasks#comment10</guid><pubDate>Wed, 17 Nov 2010 07:16:41 GMT</pubDate></item><item><title>Jeff Cyr commented on TPL: Composing tasks</title><description>@jesus
  
  
Note that you can prevent the application crash by subscribing to TaskScheduler.UnobservedTaskException:
  
  
            TaskScheduler.UnobservedTaskException += (sender, e) =&gt;
  
            {
  
                Console.WriteLine(e.Exception.ToString());
  
                e.SetObserved();
  
            };
</description><link>http://ayende.com/4692/tpl-composing-tasks#comment9</link><guid>http://ayende.com/4692/tpl-composing-tasks#comment9</guid><pubDate>Tue, 16 Nov 2010 23:24:18 GMT</pubDate></item><item><title>Dan Jasek commented on TPL: Composing tasks</title><description>I think Omer has the best solution.  I have been underwhelmed by the implementation of Task.  Cold tasks are basically useless, they forgot to make an ITask... And now Jesus' exception handling issue.
  
  
RX doesn't have any of these problems, including the need to unwrap.  It is just better thought out.
  
I hope they add some sort of iterative await for RX before they release 5.0.
</description><link>http://ayende.com/4692/tpl-composing-tasks#comment8</link><guid>http://ayende.com/4692/tpl-composing-tasks#comment8</guid><pubDate>Tue, 16 Nov 2010 20:30:38 GMT</pubDate></item><item><title>Omer Mor commented on TPL: Composing tasks</title><description>If you'd go the Rx path, composition is trivial:
  
  
        Task CreateServerConnectionAsync()
  
        {
  
            return (from sc in ServerConnection.CreateServerConnectionAsync().ToObservable()
  
                    select sc.HandShakeWithServerAsync()).Single();
  
        }
  
  
Instead of a Task, you can return an observable of unit (sort of void), and have more native Rx signature:
  
        IObservable
&lt;unit CreateServerConnectionAsync()
  
        {
  
            return from sc in ServerConnection.CreateServerConnectionAsync().ToObservable()
  
                   select sc.HandShakeWithServerAsync().ToObservable();
  
        }
  
  
If your whole API will return observables, you could also skip the .ToObservable() task conversions.
  
&gt;</description><link>http://ayende.com/4692/tpl-composing-tasks#comment7</link><guid>http://ayende.com/4692/tpl-composing-tasks#comment7</guid><pubDate>Tue, 16 Nov 2010 19:05:40 GMT</pubDate></item><item><title>Jes&amp;#250;s L&amp;#243;pez commented on TPL: Composing tasks</title><description>I forgot to include Console.ReadLine after Console.WriteLine. Anyway, it crashes
</description><link>http://ayende.com/4692/tpl-composing-tasks#comment6</link><guid>http://ayende.com/4692/tpl-composing-tasks#comment6</guid><pubDate>Tue, 16 Nov 2010 09:47:35 GMT</pubDate></item><item><title>Ayende Rahien commented on TPL: Composing tasks</title><description>Jesus,
  
Thanks.
  
The actual exception is very informative:
  
A Task's exception(s) were not observed either by Waiting on the Task or accessing its Exception property. As a result, the unobserved exception was rethrown by the finalizer thread.
  
  
Which makes total sense.
</description><link>http://ayende.com/4692/tpl-composing-tasks#comment5</link><guid>http://ayende.com/4692/tpl-composing-tasks#comment5</guid><pubDate>Tue, 16 Nov 2010 09:43:53 GMT</pubDate></item><item><title>Jes&amp;#250;s L&amp;#243;pez commented on TPL: Composing tasks</title><description>Yes it will. Try this code and see how the console application crashes:
  
  
        static void Main(string[] args)
  
        {
  
            try
  
            {
  
                var t = GetComposedTask();
  
                Thread.Sleep(1000);
  
                t.Wait();
  
                GC.Collect();
  
                GC.WaitForPendingFinalizers();
  
                Console.WriteLine("Press enter");
  
            }
  
            catch (Exception ex)
  
            {
  
                Console.WriteLine("Caugth exception {0}", ex.Message);
  
            }
  
        }
  
  
        static Task GetComposedTask()
  
        {
  
            return Task.Factory.StartNew(() =&gt; { throw new Exception("Some error ocurred"); })
  
                .ContinueWith( _ =&gt; { Console.WriteLine("Hello from task"); });
  
  
  
        }
</description><link>http://ayende.com/4692/tpl-composing-tasks#comment4</link><guid>http://ayende.com/4692/tpl-composing-tasks#comment4</guid><pubDate>Tue, 16 Nov 2010 09:35:54 GMT</pubDate></item><item><title>Ayende Rahien commented on TPL: Composing tasks</title><description>Jesus,
  
What are you talking about?
  
Exceptions inside tasks will not kill the app domain
</description><link>http://ayende.com/4692/tpl-composing-tasks#comment3</link><guid>http://ayende.com/4692/tpl-composing-tasks#comment3</guid><pubDate>Tue, 16 Nov 2010 09:11:25 GMT</pubDate></item><item><title>Jes&amp;#250;s L&amp;#243;pez commented on TPL: Composing tasks</title><description>However there is a subtle problem. If CreateServerConnection fails you will end up with an unobserved exception which will cause the entire app domain to crash if you don't catch unobserved exception in your app domain.
  
  
I use the following task extensions for composing tasks and observe antecedents:
  
  
        public static Task
&lt;tresult ObservedContinueWith
&lt;tresult(this Task task, Func
&lt;task,&gt;
 continuationFunction, TaskContinuationOptions continuationOptions)
  
        {
  
            return task.ContinueWith(t =&gt;
  
            {
  
                if (t.Status == TaskStatus.Faulted)
  
                {
  
                    throw t.Exception;
  
                }
  
                return continuationFunction(t);
  
            }, continuationOptions);
  
        }
&gt;</description><link>http://ayende.com/4692/tpl-composing-tasks#comment2</link><guid>http://ayende.com/4692/tpl-composing-tasks#comment2</guid><pubDate>Tue, 16 Nov 2010 09:05:19 GMT</pubDate></item><item><title>Ayende Rahien commented on TPL: Composing tasks</title><description>KAE,
  
Damn it!
  
I was sure that I had such an elegant solution, and then you come up with this beauty.
  
Thanks!
</description><link>http://ayende.com/4692/tpl-composing-tasks#comment1</link><guid>http://ayende.com/4692/tpl-composing-tasks#comment1</guid><pubDate>Tue, 16 Nov 2010 08:20:38 GMT</pubDate></item></channel></rss>