Reputation: 10236
I am getting my hands dirty with TPL.I stumbled upon a topic in TPL called TaskCompletionSource which is one of the ways to create a Task and it give you more control over the task by allowing developers in setting result,exception etc etc. Here is an example using task completion source
public static Task<int> RunAsyncFunction(Func<int> sampleFunction)
{
if (sampleFunction == null)
throw new NullReferenceException("Method cannot be null");
var tcs = new TaskCompletionSource<int>();
ThreadPool.QueueUserWorkItem(_ =>
{
try
{
int result = sampleFunction();
tcs.SetResult(result);
}
catch (Exception ex)
{
tcs.SetException(ex);
}
});
return tcs.Task;
}
However this is not truly asynchronus programming.It is asynchronus programming using multithreading .How can I convert this example to get it run on a single thread rather than multiple threads ? or is there any other example I can follow?
Upvotes: 0
Views: 271
Reputation: 116548
TaskCompletionSource doesn't make your code asynchronous. It's a utility to enable someone else to asynchronously await your operation.
Your operation needs to already be asynchronous on its own. For example if it's in an older paradigm, like the BeginXXX/EndXXX one.
TaskCompletionSource is mostly used to convert different types of asynchronous programming into Task based asynchronous programming.
Upvotes: 1
Reputation: 1062800
For it to be asynchronous, it needs some capacity to be completed independently in the future. That is typically via one of two things:
If you only have a single thread, and no external callback, then there really isn't any need or sense in using Task<T>
. However, you can still expose that by simply performing the calculation now, and setting the result now - or more simply: using Task.FromResult
.
However, the code you have shown is genuinely asynchronous - or more specifically: the Task<T>
that you return is. It perhaps isn't the greatest use-case, but there's nothing inherently wrong with it - except that your entire method can be hugely simplified to:
return Task.Run(sampleFunction);
The Task.Run<T>
method:
Queues the specified work to run on the ThreadPool and returns a task or Task handle for that work.
Normally, if I'm using TaskCompletionSource
, it is because I am writing IO-callback based tasks, not ThreadPool
based tasks; Task.Run
is fine for most of those.
Upvotes: 3