Sorry for the beginers question, I read a lot of post here and on the web and there is something fondemental I can't understand.
As I understood, the usage of async actions in WebAPI is mainly for scalability reasons, so any incoming request will be diverted to a worker instead to a thread and by that, more requests could be served.
My project consists on several huge actions that read/insert/update from DB by EF6 many times. the action looks like that:
public async Task<HttpResponseMessage> Get(int id)
{
PolicyModel response = await policyRepository.GetPolicyAsync(id);
return Request.CreateResponse<PolicyModel>(HttpStatusCode.OK,response);
}
and GetPolicyAsync(int id) looks like that:
public async Task<PolicyModel> GetPolicyAsync(int id)
{
PolicyModel response = new PolicyModel();
User currentUser = await Repositories.User.GetUserDetailsAsync(id);
if(currentUser.IsNew)
{
IEnumerable<Delivery> deliveries = await Repositories.Delivery.GetAvailableDeliveries();
if(deliveries == null || deliveries.Count() == 0
{
throw new Exception("no deliveries available");
}
response.Deliveries = deliveries;
Ienumerable<Line> lines = await Repositores.Delivery.GetActiveLinesAsync();
lines.AsParallel().ForAll(line => {
await Repositories.Delivery.AssignLineAsync(line,currentUser);
}
...
return response;
}
I didn't write the entire code but it goes quite a bit and it is also broken into several methods but that is the spirit of it
now the question i have is: is it a good practice to use so many awaiters in one method? I saw that it is more difficult to debug, is it hard to maintain the thread context and for the sake of worker assignment, shouldn't I just use Task.Factory.StartNew() or maybe call a simple Task.Delay() so that the request will immidiatelly be diverted to a worker?
I know that it is not a good practice (async all the way) so maybe just one async method at the end/begining of the GetpolicyAsync(int id) method
EDIT:
as I understood the mechanics of the async methods in .net, for every async method, the compiler is looking for a free thread and let it deal withthe method, the thread is looking for a free worker and assign the method to it and then report back to the compiler that it is free. so if we have 10 threads and for every thread there are 10 workers, the program can deals with 100 concurrent async methods.
so back to web developement, the IIS assign x thread to each app pool, 10 for instance. that means that the async WebAPI method can handle 100 requests but if there is another async method inside, the amount of requests that can be dealth with are 50 and so on, am I right?
and as I understood, I must call an async method in order to make the WebAPI method truely async and now, since it is a bad practice to use Task.Factory.StartNew(), I must at least use Task.Delay()
what I really want to gain is the scalability of the async WebAPI methods and the context awareness of synced methods
in all the examples I've seen so far, they only show a very simple code but in real life, methods are far more complex
Thanks
There's nothing wrong with having many awaits in a single method. If the method becomes too complicated for you you can split it up into several methods:
public async Task<PolicyModel> GetPolicyAsync(int id)
{
PolicyModel response = new PolicyModel();
User currentUser = await Repositories.User.GetUserDetailsAsync(id);
if(currentUser.IsNew)
{
await HandleDeliveriesAsync(await Repositories.Delivery.GetAvailableDeliveries());
}
...
return response;
}
public async Task HandleDeliveriesAsync(IEnumerable<Delivery> deliveries)
{
if(deliveries == null || deliveries.Count() == 0
{
throw new Exception("no deliveries available");
}
response.Deliveries = deliveries;
Ienumerable<Line> lines = await Repositores.Delivery.GetActiveLinesAsync();
lines.AsParallel().ForAll(line => {
await Repositories.Delivery.AssignLineAsync(line,currentUser);
}
Don't use Task.Factory.StartNew or Task.Delay as it just offloads the same work to a different thread. It doesn't add any value in most cases and actually harms in ASP.Net.
After much search, I came across this artical:
https://msdn.microsoft.com/en-us/magazine/dn802603.aspx
it explains what #i3arnon said in the comment. there are no workers at all, the threads are doing all the work.
In a nutshell, the thread that handles a web request reach to an opporation that is designed to be done asyncronically on the driver stack, it creates a request and pass it to the driver. The driver mark it as pending and reports "done" to the thread which goes back to the thread pool to get another assignment. The actual job is not being done by threads but by the driver that borrowing cpu time from all threads and leave them free to attend to their businesses. When the opporation is done, the driver notifies it and an available thread comes to continue...
so, from that I learn that I should look into each and every async method and check that it actually does an opporation that uses the drivers asyncronically.
Point to think: the scallability of your website is dependent on the amount of opporations that are truly being done asyncronically, if you don't have any of them, then your website won't scale.
moderators, I'm a real newbe, if I got it all wrong, please correct me
Thanks!
Related
I'm still struggeling with the async/await pattern so I'm here to ask you some precisions.
I saw this page explaining the async/await pattern pretty well. I'm posting here the example that bother me :
import 'dart:async';
Future<String> firstAsync() async {
await Future<String>.delayed(const Duration(seconds: 2));
return "First!";
}
Future<String> secondAsync() async {
await Future<String>.delayed(const Duration(seconds: 2));
return "Second!";
}
Future<String> thirdAsync() async {
await Future<String>.delayed(const Duration(seconds: 2));
return "Third!";
}
void main() async {
var f = await firstAsync();
print(f);
var s = await secondAsync();
print(s);
var t = await thirdAsync();
print(t);
print('done');
}
In this example, each async method is called one after another, so the execution time for the main function is 6 seconds (3 x 2 seconds). However, I don't understand what's the point of asynchronous function if they are executed one after another.
Are async functions not supposed to execute in the background ? Is it not the point of multiple async functions to fastens the process with parrallel execution ?
I think I'm missing something about asynchronous functions and async/await pattern in flutter so if you could explain me that, it would be very appreciated.
Best
Waiting on multiple Futures to complete using Future.wait()
If the order of execution of the functions is not important, you can use Future.wait().
The functions get triggered in quick succession; when all of them complete with a value, Future.wait() returns a new Future. This Future completes with a list containing the values produced by each function.
Future
.wait([firstAsync(), secondAsync(), thirdAsyncC()])
.then((List responses) => chooseBestResponse(responses))
.catchError((e) => handleError(e));
or with async/await
try {
List responses = await Future.wait([firstAsync(), secondAsync(), thirdAsyncC()]);
} catch (e) {
handleError(e)
}
If any of the invoked functions completes with an error, the Future returned by Future.wait() also completes with an error. Use catchError() to handle the error.
Resource:https://v1-dartlang-org.firebaseapp.com/tutorials/language/futures#waiting-on-multiple-futures-to-complete-using-futurewait
The example is designed to show how you can wait for a long-running process without actually blocking the thread. In practice, if you have several of those that you want to run in parallel (for example: independent network calls), you could optimize things.
Calling await stops the execution of the method until the future completes, so the call to secondAsync will not happen until firstAsync finishes, and so on. If you do this instead:
void main() async {
var f = firstAsync();
var s = secondAsync();
var t = thirdAsync();
print(await f);
print(await s);
print(await t);
print('done');
}
then all three futures are started right away, and then you wait for them to finish in a specific order.
It is worth highlighting that now f, s, and t have type Future<String>. You can experiment with different durations for each future, or changing the order of the statements.
If anyone new in this problem use the async . Dart has a function called FutureGroup. You can use it to run futures in parallel.
Sample:
final futureGroup = FutureGroup();//instantiate it
void runAllFutures() {
/// add all the futures , this is not the best way u can create an extension method to add all at the same time
futureGroup.add(hello());
futureGroup.add(checkLocalAuth());
futureGroup.add(hello1());
futureGroup.add(hello2());
futureGroup.add(hello3());
// call the `.close` of the group to fire all the futures,
// once u call `.close` this group cant be used again
futureGroup.close();
// await for future group to finish (all futures inside it to finish)
await futureGroup.future;
}
This futureGroup has some useful methods which can help you ie. .future etc.. check the documentation to get more info.
Here's a sample usage Example One using await/async and Example Two using Future.then.
you can always use them in a single future
final results = await Future.wait([
firstAsync();
secondAsync();
thirdAsync();
]);
results will be an array of you return type. in this case array of strings.
cheers.
Try this resolve.
final List<Future<dynamic>> featureList = <Future<dynamic>>[];
for (final Partner partner in partnerList) {
featureList.add(repository.fetchAvatar(partner.uid));
}
await Future.wait<dynamic>(featureList);
If want parallel execution you should switch to multi thread concept called Isolates
mix this with async/await concepts . You can also check this website for more
https://buildflutter.com/flutter-threading-isolates-future-async-and-await/
Using async / await like that is useful when you need a resource before executing the next task.
In your example you don't do really useful things, but imagine you call firstAsync, that gives you a stored authorization token in your phone, then you call secondAsync giving this token get asynchronously and execute an HTTP request and then checking the result of this request.
In this case you don't block the UI thread (user can interact with your app) and other tasks (get token, HTTP request...) are done in background.
i think you miss understood how flutter works first flutter is not multi threaded.....!
second if it isn't multi threaded how can it executes parallel tasks, which doesnt happen....! here is some links that will help you understand more https://webdev.dartlang.org/articles/performance/event-loop
https://www.dartlang.org/tutorials/language/futures
flutter doesn't put futures on another thread but what happens that they are added to a queue the links that i added are for event loop and how future works. hope you get it , feel free to ask me :)
at this moment I am developing an android db access to a servicestack web api.
I need to show a message of "wait please..." when the user interacts with the db, I read some documentation:
Calling from client side an async method
But I cannot found how the async method must be implemented in the webapi, serverside.
Can you please share a link to the documentation? or a simple working sample?
I have this before trying to convert it to an async call.
var response = jsonClient.Send(new UsuarioLogin { Cuenta = txtCuenta.Text, P = txtPass.Text});
After some read, the latter code is converted into this:
var response = await jsonClient.SendAsync(new UsuarioLogin { Cuenta = txtCuenta.Text, P = txtPass.Text});
So, in the server side I have this(just an extract):
public object Post(UsuarioLogin request)
{
var _usuario = usuarioRepo.Login(_cuenta, _password);
if (_usuario != null)
{
if (_usuario.UsuarioPerfilId != 2 )
{
return new UsuarioLoginResponse { Ret = -3 };
}
How can I convert it to an async method?
Thanks in advance.
Server-side and client-side async are opaque and unrelated, i.e. an async call on the client works the same way irrespective if it's calling a sync or an async service, there's also no difference for sync client either. Essentially how the server is implemented has no effect on how it's called on the client.
To make an async service on the Server you just need to return a Task, you can look at the AsyncTaskTests for different examples of how to create an async Service.
There are a lot of benefits for making non-blocking async calls on the client since this can be called from the UI thread without blocking the UI. But there's less value of server-side async which adds a lot of hidden artificial complexity, is easy to deadlock, requires rewriting I/O operations to be async and in many cases wont improve performance unless I/O is the bottleneck, e.g. async doesn't help when calling a single RDBMS. You're going to get a lot more performance benefits from using Caching instead.
My actual program is more sophisticated than this, but I've tried to simplify things.
So let's say I'm reading a file with a list of URLs. I want to download the HTML from each URL and process it. The processing may be a bit complex, so I'd like it to be done on a separate thread.
The basic problem is how to tell when all the processing is done. For example, if the user tries to close the program before all URLs are processed, I want to give him a message and not exit the program. Alternatively, I want to terminate the program (perhaps with a MsgBox("Done") message) as soon as all the URLs are processed.
I'd like my code to look something as follows (assuming I've got an outer loop reading the URLs and calling this routine)...
List<Task> TaskList = new List<Task>();
async void ProcessSingleUrl(string url) {
var web = new HttpClient();
var WebPageContents = await web.GetStringAsync(url);
Task t = Task.Run(() => ProcessWebPage(WebPageContents);
TaskList.Add(t);
}
The above code should run very quickly (Async methods run pretty well instantly) and return to the caller almost immediately.
But at that point, I may well have no entries whatsoever in TaskList, since a task isn't defined until the GetStringAsync is completed, and none (or maybe just a few) may have finished by then. So
Task.WaitAll(TaskList.ToArray());
doesn't work the way I need it to.
If absolutely necessary, I could first read in all the URLs and know how many Tasks to expect, but I'm hoping for a more elegant solution.
I suppose I could increment a counter just before the await, but that feels a bit kludgy.
I assume I'm structuring things incorrectly, but I'm not sure how to reorganize things.
Note: I'm not wedded to Task.Run. Good ol' QueueWorkItem is a possibility, but I think it has pretty well the same problems.
I assume I'm structuring things incorrectly, but I'm not sure how to reorganize things.
I think that is true. Here is a possible solution: Store the whole computation as a Task in your list, not just the second part:
async Task ProcessSingleUrlInner(string url) {
var web = new HttpClient();
var WebPageContents = await web.GetStringAsync(url);
Task t = Task.Run(() => ProcessWebPage(WebPageContents);
await t;
}
void ProcessSingleUrl(string url) {
var t = ProcessSingleUrlInner(url);
TaskList.Add(t);
}
Waiting on all tasks of this list will guarantee that everything is done. Probably, you need to adapt this idea to your exact needs.
I'm assuming that you're getting the list of urls as an IEnumerable<string> or some such.
You can use LINQ to convert each url into a Task, and then await them all to complete:
async Task ProcessUrls(IEnumerable<string> urls)
{
var tasks = urls.Select(async url =>
{
var web = new HttpClient();
var WebPageContents = await web.GetStringAsync(url);
await Task.Run(() => ProcessWebPage(WebPageContents);
});
await Task.WhenAll(tasks);
}
Note that if you use this solution and there are multiple different urls that have errors, then Task.WhenAll will only report one of those errors.
I am relating to java as to how to do thread/async. I use new Thread(target).start() where target is Runnable as one way to do threading in java. New concurrent api has alternatives but we know that on specific call new threads are creating and passed in tasks are executed.
Similarly how is async done in Dart ?
I read on send/receivport, completer/future, spawnFunction. To me only spawnFunction is convincing statement that will create new thread. can one explain how completer/future help. i know they take callbacks but is there some implicit logic/rule in javascript/dart that callbacks always be execute in different thread.
below is dart snippet/pseudo code:
void callback() {
print("callback called");
}
costlyQuery(sql, void f()) {
executeSql(sql);
f();
}
costlyQuery("select * from dual", callback);
I hope my costlyQuery signature to take function as 2nd parameter is correct. so now I do not think that f() after executeSql(sql) is going to be async. may be taking above example add completer/future if that can make async to help me understand.
tl;dr: There is no implicit rule that a callback will not block.
Javascript event queue
In Javascript, there are no threads (except WebWorkers, but that's different). This means that if any part of your code blocks, the whole application is blocked. There is nothing magic about callbacks, they are just functions:
function longLoop(cb) {
var i = 1000000;
while (i--) ;
cb();
}
function callback() {
console.log("Hello world");
}
function fun() {
longLoop(callback);
console.log("Called after Hello World is printed");
}
To make something asynchronous, the callback must be put on the event queue, which only happens through some API calls:
user initiated event handlers- clicks, keyboard, mouse
API event handlers- XmlHTTPRequest callbacks, WebWorker communication
timing functions- setTimeout, setInterval
When the event is triggered, the callback is placed on the event queue to be executed when all other callbacks have finished executing. This means that no two lines of your code will ever be executing at the same time.
Futures
I assume you have at least stumbled on this post about futures. If not, it's a good read and comes straight from the horses mouth.
In Javascript, you have to do some work to make sense of asynchronous code. There's even a Javascript library called futures for doing common things, such as asynchronous loops and sequences (full disclosure, I have personally worked with the author of this library).
The notion of a future is a promise made by the function creating the future that the future will be completed at some point down the road. If you are going to make some asynchronous call, create a future, return it, and fulfill the promise when the asynchronous call finishes. From the blog post:
Future<Results> costlyQuery() {
var completer = new Completer();
database.query("SELECT * FROM giant_table", (results) {
// when complete
completer.complete(results);
});
// this returns essentially immediately,
// before query is finished
return completer.future;
}
If database.query is a blocking call, the future will be completed immediately. This example assumes that database.query is a non-blocking call (async), so the future will be fulfilled after this function exits. completer.complete will call whatever function is passed to completer.then() with the arguments specified.
Your example, modified to be idiomatic and asynchronous:
void callback() {
print("callback called");
}
costlyQuery(sql) {
var completer = new Completer();
executeSql(sql, () => completer.complete());
return completer.future;
}
costlyQuery("select * from dual").then(callback);
This is asynchronous and uses futures correctly. You could pass your own callback function into costlyQuery as you have done and call that in the callback to executeSql to achieve the same thing, but that is the Javascript way of doing it, not the Dart way.
Isolates
Isolates are similar to Java's threads, except that isolates are a concurrency model and threads are a parallelism model (see this SO question for more information about concurrency vs parallelism).
Dart is special in that the specification does not mandate that everything be run in a single thread. It only mandates that different executing contexts do not have access to the same data. Each isolate has it's own memory and can only communicate (e.g. send data) with other isolates through send/receive ports.
These ports work similarly to channels in Go if you're familiar.
An isolate is an isolated execution context that runs independently of other code. In Javascript terms, this means that it has it's own event queue. See the Dart tour for a more complete introduction to isolates.
Lets say your executeSql is a blocking function. If we don't want to wait for it to finish, we could load it into an isolate:
void callback() {
print("callback called");
}
void costlyQuery() {
port.receive((sql, reply) {
executeSql(sql);
reply.send();
});
}
main() {
var sendPort = spawnFunction(costlyQuery);
// .call does all the magic needed to communicate both directions
sendPort.call("select * from dual").then(callback);
print("Called before executeSql finishes");
}
This code creates an isolate, sends data to it then registers a callback for when it's done. Even if executeSql blocks, main() will not necessarily block.
I'm trying to grok how C# 5's new async feature works. Suppose I want to develop an atomic increment function for incrementing an integer in a fictitious IntStore. Multiple calls are made to this function in one thread only.
async void IncrementKey(string key) {
int i = await IntStore.Get(key);
IntStore.Set(key, i+1);
}
It seems to me that this function is flawed. Two calls to IncrementKey could get the same number back from IntStore (say 5), and then set it to 6, thus losing one of the increments?
How could this be re-written, if IntStore.Get is asynchronous (returns Task) in order to work correctly?
Performance is critical, is there a solution that avoids locking?
If you are sure you are calling your function from only one thread, then there shouldn't be any problem, because only one call to IntStore.Get could be awaiting at at time. This because:
await IncrementKey("AAA");
await IncrementKey("BBB");
the second IncrementKey won't be executed until the first IncrementKey has finished. The code will be converted to a state machine. If you don't trust it, change the IntStore.Get(key) to:
async Task<int> IntStore(string str) {
Console.WriteLine("Starting IntStore");
await TaskEx.Delay(10000);
return 0;
}
You'll see that the second Starting IntStore will be written 10 seconds after the first.
To quote from here http://blogs.msdn.com/b/ericlippert/archive/2010/10/29/asynchronous-programming-in-c-5-0-part-two-whence-await.aspx The “await” operator ... means “if the task we are awaiting has not yet completed then sign up the rest of this method as the continuation of that task, and then return to your caller immediately; the task will invoke the continuation when it completes.”