I read a lot of literature but still I can’t understand how the await
and async
works. Well, even kill. Everywhere examples with httpclient, but for me they are not clear. I’m trying to figure it out myself.
That’s what I understood:
as soon as our code meets AWAIT
Return control occurs. After
completion of the expected operation method
Restores. More precisely continues
execution from the place where
Stopped when I ran into AWAit.
Good, I wrote a couple of lines of code (perhaps just did something wrong)
async task mymethod () {
int sum = 0;
await somecycleasync ();
Console.WriteLine ("Completed Cycle2");
}
ASYNC TASK SOMECYCLEASYNC () {
var Mytask = await resultofcycle ();
Console.Writeline ("Completed Cycle1");
}
ASYNC TASK & LT; INT & GT; Resultofcycle () {
int sum = 0;
For (int i = 0; i & lt; 1000000000; i ++) {
SUM + = I;
}
Return Sum;
}
Private Void Form1_Load (Object Sender, Eventargs E) {
MyMethod ();
}
-
In the
MyMethod
method, the wordawait
is found and, as far as I understand, management should go back toForm_load
, right? -
During the
method>SomecycleAsync
method, it is foundAWAIT
, i.e. By logic, the management should go toConsole.Writeline ("Cycle2");
But the result of the work is:
Completed cycle1
Cycle2
Explain to me please why? I do not understand at all
Answer 1, Authority 100%
See.
By itself, async
/ await
do not include multithreading / asynchrony. They only create conditions under which this asynchronism is easy to implement.
is actually when the async
modode is called, the following occurs.
- starts to synchronously run
ASYNC
-Metode. If this method ends until the firstAWAIT
, the result is delivered synchronously, and from the method returns the already ended , completedTask
. - If in the process of execution met
AWAIT
, the system checks whether the task has been worked on whichAWAIT
. If this task has been worked out, then its result is substituted, and synchronous execution continues on. - If the task on which
AWAIT
occurs, it has not yet been worked out, at this point from the method returned in progressTask
. At this point, the external code receives control and continues to be performed. For example, this code can recordTask
to the variable and continue to engage in your affairs. Or it can executeawait
to the receivedtask
, and since thistask
is not yet completed, the external code at this point is similar to the management of even more external code , and. etc. - When
TASK
, which isAWAIT
, will be completed (making a result or exception), the code afterawait
will resume your work.
In your case, the following happens:
- called
Form1_load
. - Stitch
MyMethod ();
. This code will produceTask
, which will later be simply ignored. - starts the
MyMethod
method. It is performed synchronouslyint sum = 0;
. To perform the next line to start, you need to performSOMECYCLEASYNC
>And thenAWAIT
on the resultingtask
. - Starts the execution of
SomecycleAsync
. To receiveTask
, according to which you need to doAWAIT
, theResultOfcycle
method>method is started. - Begins the execution of
resultofcycle ()
. Since there is no asynchronous call anywhere in it, it is fully synchronously. From the method returned to the completedTask
. - Controls returns to
SomecycleAsync
. It is performedAWAIT
onTask
obtained in the previous paragraph. Since thistask
is already completed, in the variableMyTask
simply writesint
action. The lineConsole.WriteLine is running ("Cycle1");
. This is the execution of theSomecycleAsync
method ends. Since it did not have asynchronous expectation, the completedTask
is returned. - Control is returned to the
MyMethod ()
method. Begins to runAWAIT
on the receivedTask
. SinceTASK
is complete, nothing happens, the method continues to be synchronously performed. The lineconsole.writeline ("executed cycle2") is triggered;
, the method ends returns the completedTask
- Control is returned to
Form_load
. The resultingTask
is ignored, execution ends.
It would be more correct for your purposes to explicitly launch the calculations asynchronically. For example, so:
async task mymethod () {
await somecycleasync ();
Console.Writeline ("Completed Cycle-2");
}
ASYNC TASK SOMECYCLEASYNC () {
Console.Writeline ("starts cycle");
// It launches a long calculation on the stream pool
Var Result = Await Task.run (ResultOfcycle);
Console.Writeline ("Cycle completed, Result:" + Result);
}
INT ResultOfcycle ()
{
int sum = 0;
for (int i = 0; i & lt; 1000000000; i ++)
SUM + = I;
Return Sum;
}
Private Async Void Form1_Load (Object Sender, Eventargs E)
{
await mymethod ();
}
Answer 2, Authority 8%
You resultofcycle ()
must return task & lt; int & gt;
, but returns Sum
, which is just INT
. In the method itself, there is no second stream in which it would be performed.
await
written in front of the task
object or the method returning the task
object.
Example for Task
(Calling a function that does not return anything):
static void main (String [] Args)
{
My ();
for (int i = 1; i & lt; = 10; i ++)
{
Thread.sleep (1000);
Console.Writeline ($ "* {I * 1000}");
}
Console.ReadLine ();
}
STATIC ASYNC VOID MY ()
{
AWAIT GetMessage (3000);
}
Static Task GetMessage (Int Time)
{
Return Task.run (() = & gt; {
Thread.Sleep (Time);
Console.WriteLine ($ "zxzxz {time.tostring ()}");
});
}
Example for Task & Lt; T & GT;
(call a function that returns an object type T
or in our case string
):
static void main (String [] Args)
{
My ();
for (int i = 1; i & lt; 10; i ++)
{
Thread.sleep (1000);
Console.Writeline ($ "* {I * 1000}");
}
Console.ReadLine ();
}
STATIC ASYNC VOID MY ()
{
String Message = Await GetMessage (3000);
Console.WriteLine (Message);
}
Static Task & Lt; String & GT; GetMessage (Int Time)
{
Return Task.run (() = & gt; {
Thread.Sleep (Time);
Return $ "zxzxz {time.tostring ()}";
});
}