creating a threadless task using Taskcompletion source - c#

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?

For it to be asynchronous, it needs some capacity to be completed independently in the future. That is typically via one of two things:
via a callback from an operation such as socket IO, file IO, a system timer, etc (some external source that can cause reactivation)
a second thread (possibly a queued work pool thread, like in your example)
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.

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.

Related

Does Using Async Await Avoid Thread Exhaustion?

We are troubleshooting the following performance issues on a .NET Core API endpoint:
The endpoint consistently returns in less than 500MS under minor load.
When we hit the endpoint from 3 browsers, with one request a second, it gets progressively slower (within a minute of adding a third browser making calls, response times drops to 50,000MS or worse.
Each additional browser adds threads used by the API, e.g. 40 threads base, 2nd browser hitting endpoint leads to 52 threads, third spikes to 70, and so on.
When one endpoint is loaded, the entire API returns slowly (all endpoints). This is my main reason for thinking "thread exhaustion", along with point #3.
The code currently looks like this:
public IActionResult GetPresentationByEvent(int eventid)
{
return Authorized(authDto =>
{
var eventList = _eventService.GetPresentationByEvent(eventid);
return Ok(eventList)
})
}
My theory is that return Authorized(authDto => holds a thread until it returns, leading to thread exhaustion.
public async Task<IActionResult> GetPresentationByEvent(int eventid)
{
return Authorized(async authDto =>
{
Task<List<whatever>> eventList = _eventService.GetPresentationByEvent(eventid);
return Ok(eventList)
}
}
Authorized is part of a third-party library, so I can't test this easily. Would like to know if this looks like a likely problem/solution.
Yes async await can reduce thread exhaustion. In a few words thread exhaustion arise when you generate more tasks than your ThreadPool can handle.
There are subtle specifities that you can check here : Thread starvation and queuing
The only thing that you have to keep in mind on your side is that you should never block inside a task. This implies calling asynchronous code with async await (and never using .Wait or .Result on a non finished task).
If you use some blocking code wich is not using the async await pattern you have to spawn it on a dedicated thread (not the task thread queue).
My theory is that return Authorized(authDto => holds a thread until it returns, leading to thread exhaustion.
Yes. You can easily tell whether a method is synchronous by looking at its return value. IActionResult is not an awaitable type, so this method will run synchronously.
Authorized is part of a third-party library, so I can't test this easily. Would like to know if this looks like a likely problem/solution.
Possibly. It all depends on whether Authorized can handle asynchronous delegates. If it can, then something like this would work:
public async Task<IActionResult> GetPresentationByEvent(int eventid)
{
return Authorized(async authDto =>
{
Task<List<whatever>> eventList = _eventService.GetPresentationByEventAsync(eventid);
return Ok(await eventList);
});
}
Note:
Tasks should be awaited before being passed to Ok or other helpers.
This introduces GetPresentationByEventAsync, assuming that your data-accessing code can be made asynchronous.
Since making GetPresentationByEvent asynchronous may take some work, it's worthwhile to investigate whether Authorized can take asynchronous delegates before attempting this.
Does Using Async Await Avoid Thread Exhaustion?
Yes and no. Asynchronous code (including async/await) does use fewer threads, since it avoids blocking threads. However, there is still a limit. Thread exhaustion is still possible since asynchronous code needs a free thread to complete. With asynchronous code, usually you can achieve an order of magnitude or two greater scalability before you run into scalability problems like thread exhaustion.
For more conceptual information on async ASP.NET, see this MSDN article.

Task.wait vs async await

I have been looking into upgrading the way that we do async tasks in our software. For years the software has been running in .net 2.5 and the team previous, decided to implement their own async task architecture which for the most part is OK but difficult to use for more complicated things.
I was watching a tutorial which explained tasks in C# really well but then started looking at async methods and the await keyword to keep the software up to date. My question is, why you would want to use async and await over just creating a task and using .wait/.waitAll/.waitAny.
I have read things that say that it isn't creating new threads (which suggests its not as parallel) and that it has a performance overhead.
Can you still apply the wait all one by one methodology? I am guessing since the async returns a task you would just use this to populate your list but that just furthers my argument on why would you bother using it?
My question is, why you would want to use async and await over just
creating a task and using .wait/.waitAll/.waitAny.
A task is merely a promise of your which will complete in the future. Task != Thread , and that is an important thing to remember.
I have read things that say that it isn't creating new threads (which
suggests its not as parallel) and that it has a performance overhead.
That depends on how the Task is being created.
For example:
public async Task<string> GetPageAsync(string url)
{
var httpClient = new HttpClient();
var response = await httpClient.GetAsync(url);
return response.Content.ReadAsStringAsync();
}
This operations generates no threads, but still returns a Task<string>. using async-await has some overhead because under the covers, the compiler creates a state-machine which manages the execution flow, which has to take care of many things.
While this:
return Task.Run(FooOperation);
Requests a thread pool thread to run FooOperation on.
A task can be generated for doing overlapped IO (like the first example) operations which require no thread at all. When you create a task and use Wait/WaitAll/WaitAny, you're blocking on the call, and then you end up asking yourself why use that at all and not run it synchronously instead?
For async-await, you can use the asynchronous WhenAny/WhenAll, which themselfs yield an awaitable which can be asynchronously waited.

Wrapping synchronous code into asynchronous call

I have a method in ASP.NET application, that consumes quite a lot of time to complete. A call to this method might occur up to 3 times during one user request, depending on the cache state and parameters that user provides. Each call takes about 1-2 seconds to complete. The method itself is synchronous call to the service and there is no possibility to override the implementation.
So the synchronous call to the service looks something like the following:
public OutputModel Calculate(InputModel input)
{
// do some stuff
return Service.LongRunningCall(input);
}
And the usage of the method is (note, that call of method may happen more than once):
private void MakeRequest()
{
// a lot of other stuff: preparing requests, sending/processing other requests, etc.
var myOutput = Calculate(myInput);
// stuff again
}
I tried to change the implementation from my side to provide simultaneous work of this method, and here is what I came to so far.
public async Task<OutputModel> CalculateAsync(InputModel input)
{
return await Task.Run(() =>
{
return Calculate(input);
});
}
Usage (part of "do other stuff" code runs simultaneously with the call to service):
private async Task MakeRequest()
{
// do some stuff
var task = CalculateAsync(myInput);
// do other stuff
var myOutput = await task;
// some more stuff
}
My question: Do I use the right approach to speed up the execution in ASP.NET application or am I doing unnecessary job trying to run synchronous code asynchronously?
Can anyone explain why the second approach is not an option in ASP.NET (if it is really not)?
Also, if such approach is applicable, do I need to call such method asynchronously if it is the only call we might perform at the moment (I have such case, when no other stuff there is to do while waiting for completion)?
Most of the articles in the net on this topic covers using async-await approach with the code, that already provides awaitable methods, but that's not my case. Here is the nice article describing my case, which doesn't describe the situation of parallel calls, declining the option to wrap sync call, but in my opinion my situation is exactly the occasion to do it.
It's important to make a distinction between two different types of concurrency. Asynchronous concurrency is when you have multiple asynchronous operations in flight (and since each operation is asynchronous, none of them are actually using a thread). Parallel concurrency is when you have multiple threads each doing a separate operation.
The first thing to do is re-evaluate this assumption:
The method itself is synchronous call to the service and there is no possibility to override the implementation.
If your "service" is a web service or anything else that is I/O-bound, then the best solution is to write an asynchronous API for it.
I'll proceed with the assumption that your "service" is a CPU-bound operation that must execute on the same machine as the web server.
If that's the case, then the next thing to evaluate is another assumption:
I need the request to execute faster.
Are you absolutely sure that's what you need to do? Are there any front-end changes you can make instead - e.g., start the request and allow the user to do other work while it's processing?
I'll proceed with the assumption that yes, you really do need to make the individual request execute faster.
In this case, you'll need to execute parallel code on your web server. This is most definitely not recommended in general because the parallel code will be using threads that ASP.NET may need to handle other requests, and by removing/adding threads it will throw the ASP.NET threadpool heuristics off. So, this decision does have an impact on your entire server.
When you use parallel code on ASP.NET, you are making the decision to really limit the scalability of your web app. You also may see a fair amount of thread churn, especially if your requests are bursty at all. I recommend only using parallel code on ASP.NET if you know that the number of simultaneous users will be quite low (i.e., not a public server).
So, if you get this far, and you're sure you want to do parallel processing on ASP.NET, then you have a couple of options.
One of the easier methods is to use Task.Run, very similar to your existing code. However, I do not recommend implementing a CalculateAsync method since that implies the processing is asynchronous (which it is not). Instead, use Task.Run at the point of the call:
private async Task MakeRequest()
{
// do some stuff
var task = Task.Run(() => Calculate(myInput));
// do other stuff
var myOutput = await task;
// some more stuff
}
Alternatively, if it works well with your code, you can use the Parallel type, i.e., Parallel.For, Parallel.ForEach, or Parallel.Invoke. The advantage to the Parallel code is that the request thread is used as one of the parallel threads, and then resumes executing in the thread context (there's less context switching than the async example):
private void MakeRequest()
{
Parallel.Invoke(() => Calculate(myInput1),
() => Calculate(myInput2),
() => Calculate(myInput3));
}
I do not recommend using Parallel LINQ (PLINQ) on ASP.NET at all.
I found that the following code can convert a Task to always run asynchronously
private static async Task<T> ForceAsync<T>(Func<Task<T>> func)
{
await Task.Yield();
return await func();
}
and I have used it in the following manner
await ForceAsync(() => AsyncTaskWithNoAwaits())
This will execute any Task asynchronously so you can combine them in WhenAll, WhenAny scenarios and other uses.
You could also simply add the Task.Yield() as the first line of your called code.
this is probably the easiest generic way in your case
return await new Task(
new Action(
delegate () {
// put your synchronous code here
}
)
);

async /await for methods in wpf aplication

I have such question. For example I create dynamically custom userControl using mvvm pattern. So I've sended a command to create an userControl. So creation looks like
private async Task<bool> OnAddUserControl1(List<ALV_VM_ADWERT> control)
{
try
{
_cancellationTokenSource = new CancellationTokenSource();
var userControl = _userControlsContainer.CreateUserControl1(control);
var task1 = Task.Factory.StartNew(() =>
{
userControl.ViewModel.InOperationEvent += OnUsercontrolInOperationChanged;
userControl.ViewModel.ValueTypeChangedEvent += OnValueTypeChanged;
userControl.ViewModel.SetExpandableName += OnSetExpandableName;
}, _cancellationTokenSource.Token, TaskCreationOptions.AttachedToParent, TaskScheduler.FromCurrentSynchronizationContext());
var task2 = Task.Factory.StartNew(() => FinalCreatingStep(userControl, control[0].RAUMNAME.Trim()), _cancellationTokenSource.Token, TaskCreationOptions.AttachedToParent, TaskScheduler.FromCurrentSynchronizationContext());
await Task.WhenAll(task1, task2);
return true;
}
catch (Exception)
{
return false;
}
}
and my question is - does it make sence to create child tasks, or it is better to have code without child tasks? And if the answer is yes, then should I make all methods async? If not, what methods I should not make async?
Do those event subscriptions really need to be asynchronous? You may be trying too hard to use asynchronous code.
The user control constructor is usually the most time consuming part and must be done on the UI thread. Asynchronous operations are generally only required when some form of IO or processing is involed;
Reading Files
Writing Files
Processing large data sets
Crossing the process boundary to talk to a server or connect device
In short, an asynchronous task is probably overkill here.
Does it make sence to create child tasks, or it is better to have code without child tasks?
It is depending on your requirements. If your UI will blocked (Freeze) for long time you have to create a child task, otherwise not!
And if the answer is yes, then should I make all methods async? If not, what methods I should not make async?
Here it is also depending on your requirements and your .Net Version. If you are using .NET 4.5 the easiest way to do that with Async await. If you are using .Net 3.5 than just use Task. If .Net 2 use BackgorundWorker else use Thread class. ONLY Asynchrony methods must get the word async. Other methods you do not have to change them. In other words only the method which blocked the UI.
Your current code doesn't make any sense.
The point of async code in a UI application is responsiveness - i.e., moving long-running operations off the UI thread. As #Gusdor pointed out, most of the use cases for async are I/O-based (or event-based) operations, where you don't want to block the UI thread just to wait for some result. Another use case is when you have some CPU-bound work to do, but you don't want to tie up the UI thread; in this case, you can use Task.Run.
But in your code, you're calling StartNew with TaskScheduler.FromCurrentSynchronizationContext, which means your "child" tasks are going to execute on the UI thread. So your OnAddUserControl1 is just starting tasks which will run on the same thread and asynchronously waiting for them to complete. This is a very complex way of doing nothing.
While we're on the subject of StartNew, there are a number of other problems:
The code is passing a CancellationToken without ever observing it in the delegate.
The code is specifying AttachedToParent which is incorrect for await-compatible tasks.
As mentioned above, the code is passing a TaskScheduler which will run the delegate right back on the UI thread.
If you need to use background (thread pool) tasks, you should use Task.Run instead of Task.Factory.StartNew; I go into more detail on my blog.
So for this example, it doesn't make sense to use async or await at all.
The best way to start using async is to identify the I/O-bound (or event-driven) parts first (e.g., HTTP requests, database calls), make them async, and then work your way up the call stack.

Continuation with Tasks (instead of delegates)

I have a class where each method execute asynchronously, i.e. return a Task, but where each method should nevertheless wait for the completion of the preceding call.
Continuation, right?
Except that a task continuation takes a delegate (Action) in parameter, not another task.
I've tried different things and the best I could do to make it work is the following (to me quite complex) code:
private Task QueueTask(Func<Task> futureTask)
{
var completionSource = new TaskCompletionSource<int>();
_lastTask.ContinueWith(async t =>
{
try
{
await futureTask();
completionSource.SetResult(0);
}
catch (Exception ex)
{
completionSource.SetException(ex);
}
});
_lastTask = completionSource.Task;
return _lastTask;
}
Here _lastTask is a private member of my class. Since all calls are coming from the UI thread, I just keep the last task and put continuation on it.
As I said I find this code quite convoluted. Do you have a better suggestion?
To me, it seems like you're asking the wrong question. A queue of tasks like this is an unusual requirement. We don't know anything about the actual problem you're trying to solve, so we can't suggest better approaches.
ContinueWith is intended for dynamic parallel processing, so it doesn't quite fit in with async code. However, you can use ContinueWith paired with Unwrap to sort-of emulate the behavior of await (if you ignore how await interacts with the current context).
So you can simplify your queue of tasks solution as such:
private Task QueueTask(Func<Task> futureTask)
{
_lastTask = _lastTask.ContinueWith(t => futureTask()).Unwrap();
return _lastTask;
}
However, there are probably better solutions. If the purpose of the queue is to provide exclusive access, a SemaphoreSlim would be more natural. If you actually do need a queue for some reason, consider using a Dataflow mesh.

Categories

Resources