13

There's something unclear to me about the inner workings of TaskCompletionSource<>.

When creating a simple Task<> using the Factory, I expect this task to be enqueued in a thread pool, unless I specify TaskCreationOptions.LongRunning, where it will run in a new thread instead.

My understanding of TaskCompletionSource, is that I am responsible of triggering when a task ends, or fails, and I have full control on how to manage threads. However, the ctor of TaskCompletionSource allows me to specify a TaskCreationOptions, and this confuse me, since I was expecting the Scheduler not being able to handle the task itself.

What is the purpose of TaskCreationOptions in the context of a TaskCompletionSource<>?

Here is an example of use:

public Task<WebResponse> Download(string url)
{
    TaskCompletionSource<WebResponse> tcs = 
    new TaskCompletionSource<WebResponse>(TaskCreationOptions.LongRunning);

    var client = (HttpWebRequest)HttpWebRequest.Create(url);
    var async = client.BeginGetResponse(o =>
      {
          try
          {
              WebResponse resp = client.EndGetResponse(o);
              tcs.SetResult(resp);
          }
          catch (Exception ex)
          {
              tcs.SetException(ex);
          }
      }, null);


    return tcs.Task;
}
abatishchev
  • 98,240
  • 88
  • 296
  • 433
uzul
  • 1,096
  • 9
  • 23
  • 2
    Well, you can see what was used through the resulting task, so I suppose it's possible that some code could be passed a TCS or a Task and do something based on the result of one of those options (in the custom code that is processing this task). – Servy Jan 15 '13 at 19:07

1 Answers1

4

The answer is that a TaskCreationOption is useful for its AttachToParent option only, as TaskCompletionSource can be the child of any other task. Options related to thread management or execution ordering aren't relevant in the context of a TaskCompletionSource. The following code actually throws an exception:

new TaskCompletionSource<WebResponse>(TaskCreationOptions.LongRunning);
uzul
  • 1,096
  • 9
  • 23
  • Suppose I call your method with `await Download("http://example.com")`, does attachment matter? I would guess that I am implicitly attached based on the fact that I'm awaiting the result... or is there more to it? – gzak Oct 08 '14 at 08:28
  • Sorry for late answer, as you probably know `await Download("http://example.com")` is just syntaxic sugar for `Download("http://example.com").ContinueWith( task => { /* then */}`. So parent/child attachment is a relevant possibility, but this is probably bad practice. – uzul Apr 01 '15 at 21:50
  • Ah not so. TaskCreationOptions.RunContinuationsAsynchronously is really useful on TaskCompletionSource. – Joshua Jan 25 '21 at 23:20