-1

in a discussion on asynchronous programming in C# the author speaks matter of factly of "puppet tasks". It shows up in various places on stack overflow. But it is only used, never explained. Here are some examples of where it is mentioned here, here, here, and in the book Async in C# 5.0.

What should I make of puppet tasks or puppets in programming? Is it indicating some mockup? A task wrapper or what?
Thank you.

Community
  • 1
  • 1
Andi
  • 57
  • 4
  • Can you provide a reference to these discussions? – Jeroen Vannevel Aug 23 '15 at 18:16
  • 1
    There is a bit of software that is called puppet and has tasks, but without actual links or quotes or context, we can't answer this for you definitively. Since you say these are on stack overflow, you should be able to quote a specific example. – George Stocker Aug 23 '15 at 18:17
  • 2
    This is a valid question. Not sure why it's on-hold. It's a term used in C# async quite heavily. Since I can't post an answer, I'll respond here. It basically refers to using `TaskCompletionSource` to implement the Task Asynchronous Pattern on an API that uses some other async pattern (Begin/End, callback events, etc.) Essentially, the "other" async pattern is using a Task simply as a "puppet" to do it's bidding. It really does all the work, the Task is just there to make it so you can use TPL and async/await. – dmeglio Aug 23 '15 at 18:19
  • @dman2306: please post your comment as an answer. – Sam Axe Aug 23 '15 at 22:18
  • @SamAxe Unfortunately dman2306 does not yet have enough rep to post an answer. – Eris Aug 23 '15 at 23:26

1 Answers1

3

Before the creation of Task in C#, Microsoft had implemented other means of creating asynchronous events. One was the Event-Asynchronous Pattern (EAP), where a callback method is fired when the asynchronous event finishes. Another is the Asynchronous Programming Model (APM) which uses IAsyncResult and Begin/End style methods.

When the Task-based Asynchronous Pattern (TAP) was added, Microsoft made a concerted effort to add Task based versions of all of the async APIs in the BCL. However, they couldn't do everything, and on top of that, many third-party libraries were already out there using either EAP or APM. At the same time though, they realized the value of using the TAP and the value async and await bring. As a result, they created the TaskCompletionSource. This serves as a wrapper to make non-TAP APIs work with TAP. Essentially, you create what many refer to as a puppet task. This is a task that really only exists to turn an EAP or APM (or other async pattern) method into a TAP method. For example, say you have a class, DownloadFile. This class fires a DownloadComplete event when the file is done. Normally you'd do something like:

DownloadFile myfile = new DownloadFile();
myfile.Complete += SomeMethodToHandleCompletion;
myfile.Download();

Then, at some point your method fires. That's great, but we want tasks. So what you could do is something like:

public Task<string> DownloadFileAsync(string url)
{
    var tcs = new TaskCompletionSource<string>(); 
    DownloadFile myfile = new DownloadFile(url);

    myfile.Complete += (theData) =>
    {
        tcs.SetResult(theData);
    };

    return tcs.Task;
}

That's a simplistic example since I'm not handling exceptions or anything, but essentially, now I've turned an event handler (EAP) into something I can use with async/await by creating a "puppet task" that simply does the bidding of the event. When the event finishes, we simply say "hey the Task is done too". As a result, the following works:

string downloadedFile = await DownloadFileAsync("http://www.some.url.example");
dmeglio
  • 2,830
  • 1
  • 19
  • 24