В моем понимании одна из основных вещей, которые async
и ждут
сделать, чтобы сделать код легко писать и читать - но, используя их равными для создания фоновых потоков для выполнения длительных логика?
Я'm В настоящее время опробовать самый простой пример. Я'ве добавил некоторые комментарии рядный. Можете ли вы прояснить это для меня?
// I don't understand why this method must be marked as `async`.
private async void button1_Click(object sender, EventArgs e)
{
Task<int> access = DoSomethingAsync();
// task independent stuff here
// this line is reached after the 5 seconds sleep from
// DoSomethingAsync() method. Shouldn't it be reached immediately?
int a = 1;
// from my understanding the waiting should be done here.
int x = await access;
}
async Task<int> DoSomethingAsync()
{
// is this executed on a background thread?
System.Threading.Thread.Sleep(5000);
return 1;
}
При использовании async
и ждут
компилятор создает государственную машину в фоновом режиме.
Здесь'ы пример, на котором я надеюсь, я могу объяснить некоторые высокопоставленные детали, которые идут на:
public async Task MyMethodAsync()
{
Task<int> longRunningTask = LongRunningOperationAsync();
// independent work which doesn't need the result of LongRunningOperationAsync can be done here
//and now we call await on the task
int result = await longRunningTask;
//use the result
Console.WriteLine(result);
}
public async Task<int> LongRunningOperationAsync() // assume we return an int from this long running operation
{
await Task.Delay(1000); // 1 second delay
return 1;
}
Итак, что происходит здесь:
Задача И Л;int> longRunningTask = LongRunningOperationAsync();исполняет
LongRunningOperation`
Самостоятельная работа осуществляется на позвольте'ы взять на себя основной поток (идентификатор потока = 1) тогда жду longRunningTask` достигается.
Теперь, если longRunningTask
ничего'т закончил и все еще работает, MyMethodAsync()
вернет в вызывающий метод, таким образом, основной поток не'т быть заблокирован. Когда longRunningTaskбудет сделано, то поток из пула потоков (может быть какие-нить) вернется к
MyMethodAsync () в своем предыдущем контексте и продолжить выполнение (в данном случае выводит результат в консоль).
Второе дело будет в том, что longRunningTask
уже закончил свое выполнение и результат налицо. При достижении ожидают longRunningTaskу нас уже есть результат, поэтому выполнение кода продолжится по той же теме. (в этом случае результат печати на консоль). Конечно, это не так, для приведенного выше примера, где там'в задачи С. Задержка(1000)
участвует.
и GT; в моем понимании одна из главных вещей, что async и await сделать, чтобы сделать код легко писать и читать.
Они'вновь сделать асинхронные код легко писать и читать, да.
это то же самое, что нерестовый фоновых потоков для выполнения длинных логических продолжительность?
Не на всех.
и GT; // я не'т понять, почему этот метод должен быть помечен как 'асинхронные'.
В "асинхронный" ключевое слово позволяет ждут
ключевое слово. Поэтому любой метод, используя ждут
должны быть помечены как "асинхронный".
// эта строка будет достигнут после 5 секунд сна от DoSomethingAsync() метод. Должны'т быть немедленно достигнуты?
Нет, потому что методы async` не запустить в другом потоке по умолчанию.
// это выполняется в фоновом потоке?
Нет.
Вы можете найти асинхронный
/ждут
интро полезные. Официальном сайте MSDN документы также необыкновенно хороша (в частности, кран разделе), и команда "асинхронный" потушить отличным чаво.
Вот краткий пример асинхронного/ждут на высоком уровне. Есть много более детально рассмотреть за этого.
Примечание: Задача.Задержка(1000)` имитирует выполнение работы в течение 1 секунды. Я думаю, что это'ы лучше думать об этом, так как ждали ответа от внешних ресурсов. Поскольку наш код ждет ответа, система может установить задачу в сторону и вернись к нему после того, как он'ы закончили. Между тем, он может делать другую работу на что-нить.
В приведенном ниже примере первый блок делает именно это. Начинается все задания сразу (на задачи.Задержка линии) и устанавливает их в сторону. Код будет пауза На ждать
до 1 секунды задержка делается перед походом на следующую строку. С В
, С
, D
и Е
все приступили к выполнению почти в то же самое время как а
(из-за отсутствия ждут), они должны закончить примерно в то же время в этом случае.
В приведенном ниже примере второй блок начинает задание и ждет его завершения (то есть, что ждут
делает) перед началом последующих задач. Каждая итерация это занимает 1 секунду. В ждут
приостановка программы и ждем результата, прежде чем продолжить. Это основная разница между первым и вторым блоками.
Console.WriteLine(DateTime.Now);
// This block takes 1 second to run because all
// 5 tasks are running simultaneously
{
var a = Task.Delay(1000);
var b = Task.Delay(1000);
var c = Task.Delay(1000);
var d = Task.Delay(1000);
var e = Task.Delay(1000);
await a;
await b;
await c;
await d;
await e;
}
Console.WriteLine(DateTime.Now);
// This block takes 5 seconds to run because each "await"
// pauses the code until the task finishes
{
await Task.Delay(1000);
await Task.Delay(1000);
await Task.Delay(1000);
await Task.Delay(1000);
await Task.Delay(1000);
}
Console.WriteLine(DateTime.Now);
Выход:
5/24/2017 2:22:50 PM
5/24/2017 2:22:51 PM (First block took 1 second)
5/24/2017 2:22:56 PM (Second block took 5 seconds)
Примечание: это где вещи становятся для меня немного в тумане, так что, если я'м неправильно на что-нибудь, пожалуйста, поправьте меня и я буду обновлять ответ. Это's важный, чтобы иметь базовое понимание, как это работает, но вы можете получить, не будучи экспертом по нему так долго, как вы никогда не использовать ConfigureAwait(ложь), хотя вы, вероятно, упустить какую-то возможность для оптимизации, я полагаю.
Есть один аспект, который делает асинхронный/ждут концепция несколько сложнее для понимания. Что's не то, что в данном примере, это все происходит в одном потоке (или, по крайней мере, как представляется, тот же поток в отношении ее SynchronizationContext). По умолчанию, ждут
восстановим контекст синхронизации исходный поток, что он работает на. Например, в ASP.NET у вас есть свойство HttpContext, который привязан к нити, когда запрос приходит. Этот контекст содержит все характерные для оригинального HTTP-запроса, такие как исходный объект запроса, который имеет такие вещи, как язык, IP-адрес, заголовки и т. д. Если вы переключитесь на полпути потоков путем обработки что-то, вы могли бы потенциально в конечном итоге пытается вытянуть информацию из этого объекта на другой объект HttpContext, который может иметь катастрофические последствия. Если вы знаете, что вы выиграли'т быть с помощью контекстного ни к чему, вы можете выбрать, чтобы "пофиг" около нее. В основном это позволяет ваш код должен выполняться в отдельном потоке без привлечения контексте с ним.
Как вы достигаете этого? По умолчанию ждут; код на самом деле делает предположение, что вы хотите, чтобы захватить и восстановить контекст:
await a; //Same as the line below
await a.ConfigureAwait(true);
Если вы хотите, чтобы основной код для продолжения в новом потоке без оригинального контекста, вы просто используете false вместо True, поэтому она знает, что это не'т нужно восстановить контекст.
await a.ConfigureAwait(false);
После того как программа сделала паузы, он будет продолжать potentially на совершенно другом потоке с другим контекстом. Это где улучшение производительности придет-оно может продолжаться на любом доступном потоке без необходимости восстановления первоначального контекста и началось.
Это такое заблуждение? Черт возьми, да! Можете ли вы понять это? Наверное! После того, как вы понимаете понятия, потом перейдем к Стивен Клири'ы объяснения которые, как правило, больше ориентированы на кого-то, обладающего техническими знаниями асинхронный/ждут уже.
Далее на другие ответы, посмотрите на ждать (Справочник по c#)
и более конкретно на примере включенными, то это объясняет вашу ситуацию
ждут > следующие окна формы пример иллюстрирует использование в
метод async, WaitAsynchronouslyAsync. Сравните поведение этого метод с поведением WaitSynchronously. Без ожидания оператор, примененный к задаче, WaitSynchronously работает синхронно несмотря на использование модификатора async в определении и вызове резьба.Спать в его тело.
private async void button1_Click(object sender, EventArgs e)
{
// Call the method that runs asynchronously.
string result = await WaitAsynchronouslyAsync();
// Call the method that runs synchronously.
//string result = await WaitSynchronously ();
// Display the result.
textBox1.Text += result;
}
// The following method runs asynchronously. The UI thread is not
// blocked during the delay. You can move or resize the Form1 window
// while Task.Delay is running.
public async Task<string> WaitAsynchronouslyAsync()
{
await Task.Delay(10000);
return "Finished";
}
// The following method runs synchronously, despite the use of async.
// You cannot move or resize the Form1 window while Thread.Sleep
// is running because the UI thread is blocked.
public async Task<string> WaitSynchronously()
{
// Add a using directive for System.Threading.
Thread.Sleep(10000);
return "Finished";
}
Показав выше объяснения в действии в простой консольной программы -
class Program
{
static void Main(string[] args)
{
TestAsyncAwaitMethods();
Console.WriteLine("Press any key to exit...");
Console.ReadLine();
}
public async static void TestAsyncAwaitMethods()
{
await LongRunningMethod();
}
public static async Task<int> LongRunningMethod()
{
Console.WriteLine("Starting Long Running method...");
await Task.Delay(5000);
Console.WriteLine("End Long Running method...");
return 1;
}
}
А на выходе:
Starting Long Running method...
Press any key to exit...
End Long Running method...
Таким образом,
Таким образом, не поток блокируется.
Я думаю, что вы'вэ взял плохой пример с Системы.Резьбонарезной.Нить.Сон
Точки "асинхронный" задача-позволить ему выполнить в фоновом режиме без блокировки основного потока, например, сделав DownloadFileAsync
Системы`.Резьбонарезной.Нить.Сон-это'т то, что есть "делается", он просто спит, и поэтому ваш следующей строке достигается через 5 секунд ...
Прочитав эту статью, я думаю, что это прекрасное объяснение async
и концепция ждут
: http://msdn.microsoft.com/en-us/library/vstudio/hh191443.aspx
Вот программа быстрая консоли, чтобы было понятно для тех, кто следовать. В "TaskToDo и" способ ваш давно работает метод, который вы хотите сделать асинхронный. Что делает его запустить асинхронный делается методом TestAsync. Тест петли метод просто проходит через "и TaskToDo на" задачи и выполняет их асинхронности. Вы можете увидеть, что в результатах, поскольку они не'т заполнить в том же порядке от запуска к запуску - они представляют отчеты в интерфейсе консоли нить, когда они заканчивают. Упрощенно, но я думаю, что упрощенные примеры основного узора лучше, чем больше задействовано примеры:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace TestingAsync
{
class Program
{
static void Main(string[] args)
{
TestLoops();
Console.Read();
}
private static async void TestLoops()
{
for (int i = 0; i < 100; i++)
{
await TestAsync(i);
}
}
private static Task TestAsync(int i)
{
return Task.Run(() => TaskToDo(i));
}
private async static void TaskToDo(int i)
{
await Task.Delay(10);
Console.WriteLine(i);
}
}
}
Все ответы здесь используют задач.Задержка() или некоторые другие встроенные функции async. Но вот мой пример, что использовать ни один из этих асинхронных функций:
// Starts counting to a large numbewr and then immediately displays message "i'm counting...".
// Then it waits for task to finish and displays "finished, press any key".
static void asyncTest ()
{
Console.WriteLine("Started asyncTest()");
Task<long> task = asyncTest_count();
Console.WriteLine("Started counting, please wait...");
task.Wait(); // if you comment this line you will see that message "Finished counting" will be displayed before we actually finished counting.
//Console.WriteLine("Finished counting to " + task.Result.ToString()); // using task.Result seems to also call task.Wait().
Console.WriteLine("Finished counting.");
Console.WriteLine("Press any key to exit program.");
Console.ReadLine();
}
static async Task<long> asyncTest_count()
{
long k = 0;
Console.WriteLine("Started asyncTest_count()");
await Task.Run(() =>
{
long countTo = 100000000;
int prevPercentDone = -1;
for (long i = 0; i <= countTo; i++)
{
int percentDone = (int)(100 * (i / (double)countTo));
if (percentDone != prevPercentDone)
{
prevPercentDone = percentDone;
Console.Write(percentDone.ToString() + "% ");
}
k = i;
}
});
Console.WriteLine("");
Console.WriteLine("Finished asyncTest_count()");
return k;
}
Этот ответ призван предоставить какую-либо информацию, характерные для ASP.NET.
С помощью ключевого слова async/await в контроллер MVC, можно увеличить использование пула потоков и достичь гораздо более высокой пропускной способности, как описано в статье ниже,
http://www.asp.net/mvc/tutorials/mvc-4/using-asynchronous-methods-in-aspnet-mvc-4
В web-приложениях, что видит большое количество одновременных запросов на запуск или нагрузкой пульсирующего (где параллелизм вдруг увеличивается), делая эти вызовы веб-службы асинхронных увеличит отзывчивость вашего приложения. Асинхронный запрос подает В то же время как синхронный запрос. Например, если запрос делает вызов веб-службы, которая требует двух секунд полная, запрос занимает две секунды, выступал ли он синхронно или асинхронно. Однако при асинхронном вызове поток не заблокирован для ответов на другие запросы во время ждет первого запроса. Таким образом, асинхронный просит предотвратить очереди пула потоков и роста, когда есть много одновременных запросов, которые вызывают длительных операций.
Чтобы быть честным, я все еще думаю, что лучшее объяснение о будущем и обещает на Википедии: http://en.wikipedia.org/wiki/Futures_and_promises
Основная идея заключается в том, что у вас есть отдельный пул потоков, которые выполняют задачи асинхронно. При ее использовании. Однако объект делает обещание, что он будет выполнять операции на некоторое время и дать вам результат, когда вы просите его. Это означает, что он будет блокировать, когда вы запрашиваете результат и еще'т закончил, но выполнение в пул потоков, в противном случае.
Оттуда вы можете оптимизировать вещи: некоторые операции могут быть реализованы с использованием ключевых слов async и вы можете оптимизировать такие вещи, как файл ввода-вывода и сетевого взаимодействия при объединении последующие запросы и/или изменение порядка их. Я'м не уверен, если это уже в рамках задач из Microsoft, - но если это'т, что будет одним из первых вещей, которые я хотел бы добавить.
Вы можете реализовать в будущем какой-то шаблон с доходностью в C# 4.0. Если вы хотите знать, как это работает точно так же, я могу рекомендовать эту ссылку, что делает достойную работу: http://code.google.com/p/fracture/source/browse/trunk/Squared/TaskLib/ . Однако, если вы начинаете играя с ним самостоятельно, вы заметите, что вам действительно нужно поддерживать язык, если вы хотите сделать все классные вещи-это именно то, что Microsoft сделала.
На самом деле асинхронный / ждут пара ключевых слов, которые являются просто синтаксическим сахаром для создания обратного вызова асинхронной задачи.
Взять к примеру эту операцию:
public static void DoSomeWork()
{
var task = Task.Run(() =>
{
// [RUNS ON WORKER THREAD]
// IS NOT bubbling up due to the different threads
throw new Exception();
Thread.Sleep(2000);
return "Hello";
});
// This is the callback
task.ContinueWith((t) => {
// -> Exception is swallowed silently
Console.WriteLine("Completed");
// [RUNS ON WORKER THREAD]
});
}
Приведенный выше код имеет ряд недостатков. Ошибки не прошли, и он'ы трудно читать. Но async и await прийти к нам на помощь:
public async static void DoSomeWork()
{
var result = await Task.Run(() =>
{
// [RUNS ON WORKER THREAD]
// IS bubbling up
throw new Exception();
Thread.Sleep(2000);
return "Hello";
});
// every thing below is a callback
// (including the calling methods)
Console.WriteLine("Completed");
}
Ждать звонков должны быть в асинхронных методов. Это имеет некоторые преимущества:
Примечание: async и await используются с асинхронные вызовы не чтобы сделать эти. Вы должны использовать задачи библиотеки для этого, как и задач.Запустить() .
Вот сравнение между ждать и не дождаться решения
Это не асинхронные решение:
public static long DoTask()
{
stopWatch.Reset();
stopWatch.Start();
// [RUNS ON MAIN THREAD]
var task = Task.Run(() => {
Thread.Sleep(2000);
// [RUNS ON WORKER THREAD]
});
// goes directly further
// WITHOUT waiting until the task is finished
// [RUNS ON MAIN THREAD]
stopWatch.Stop();
// 50 milliseconds
return stopWatch.ElapsedMilliseconds;
}
Это асинхронный метод:
public async static Task<long> DoAwaitTask()
{
stopWatch.Reset();
stopWatch.Start();
// [RUNS ON MAIN THREAD]
await Task.Run(() => {
Thread.Sleep(2000);
// [RUNS ON WORKER THREAD]
});
// Waits until task is finished
// [RUNS ON MAIN THREAD]
stopWatch.Stop();
// 2050 milliseconds
return stopWatch.ElapsedMilliseconds;
}
Вы на самом деле можете вызвать асинхронный метод без ключевого слова await, но это означает, что любое исключение здесь глотают в режиме релиза:
public static Stopwatch stopWatch { get; } = new Stopwatch();
static void Main(string[] args)
{
Console.WriteLine("DoAwaitTask: " + DoAwaitTask().Result + " ms");
// 2050 (2000 more because of the await)
Console.WriteLine("DoTask: " + DoTask() + " ms");
// 50
Console.ReadKey();
}
Async и await не предназначены для параллельных вычислений. Они используются, чтобы не блокировать основной поток. Когда он's о asp.net или Windows приложений, блокирует основной поток из-за сетевой вызов-это плохо. Если вы сделаете это, ваше приложение будет вам отвечать или даже аварии.
Проверьте МС документы дополнительные примеры.
Видите эту скрипку https://dotnetfiddle.net/VhZdLU (и улучшить его, если это возможно) для запуска простое консольное приложение который показывает использование задача, задача.WaitAll(), async и await операторы в той же программе.
Этот огурчик должен очистить свое исполнение концепции цикла.
Вот пример кода
using System;
using System.Threading.Tasks;
public class Program
{
public static void Main()
{
var a = MyMethodAsync(); //Task started for Execution and immediately goes to Line 19 of the code. Cursor will come back as soon as await operator is met
Console.WriteLine("Cursor Moved to Next Line Without Waiting for MyMethodAsync() completion");
Console.WriteLine("Now Waiting for Task to be Finished");
Task.WaitAll(a); //Now Waiting
Console.WriteLine("Exiting CommandLine");
}
public static async Task MyMethodAsync()
{
Task<int> longRunningTask = LongRunningOperation();
// independent work which doesn't need the result of LongRunningOperationAsync can be done here
Console.WriteLine("Independent Works of now executes in MyMethodAsync()");
//and now we call await on the task
int result = await longRunningTask;
//use the result
Console.WriteLine("Result of LongRunningOperation() is " + result);
}
public static async Task<int> LongRunningOperation() // assume we return an int from this long running operation
{
Console.WriteLine("LongRunningOperation() Started");
await Task.Delay(2000); // 2 second delay
Console.WriteLine("LongRunningOperation() Finished after 2 Seconds");
return 1;
}
}
Асинхронный & ждут простое объяснение
Простая Аналогия
Человек может ждать на их утренний поезд. Это все, что они делают-это их первостепенная задача, которую они выполняют в настоящее время. (синхронно программирования (что вы обычно делаете!))
Другой человек может ждите утром их поезд, пока они курят сигарету, а затем выпить чашечку кофе. (Асинхронное программирование)
Что такое асинхронное программирование?
Асинхронного программирования, где программист будет выбрать для запуска своего кода в отдельном потоке от основного потока выполнения, а затем уведомлять основной поток на нем's заполнение.
Какое ключевое слово async самом деле?
Добавив ключевое слово async в имени метода, как
async void DoSomething(){ . . .
позволяет программисту использовать await при вызове асинхронной задачи. Что's все, что он делает.
Почему это важно?
Во многих программных систем основной поток отведенное для операций, непосредственно относящиеся к пользовательскому интерфейсу. Если я использую очень сложный рекурсивный алгоритм, который длится 5 секунд на моем компьютере, но когда я на основной поток (поток пользовательского интерфейса), когда пользователь пытается нажать на что-либо по моему заявлению, он будет заморожен, как мой основной поток очереди и в настоящее время выполняется слишком много операций. В результате основной поток не может обработать щелчок мыши, чтобы запустить метод с нажатием кнопки.
Когда вы используете async и await?
Используйте асинхронные ключевые слова в идеале, когда вы делаете что-нибудь, что не'т привлекать пользовательский интерфейс.
Итак, допустим, вы'повторно написать программу, которая позволяет пользователю эскиз на свой мобильный телефон, но каждые 5 секунд он будет проверять погоду в интернете.
Мы должны быть в ожидании вызова избирательных звонки каждые 5 секунд в сеть, чтобы получить погоду, как пользователь приложения должен продолжать взаимодействовать с мобильного сенсорный экран, чтобы рисовать красивые картинки.
Как вы используете async и await
Исходя из приведенного выше примера, вот некоторые псевдо-код, как написать это:
//ASYNCHRONOUS
//this is called every 5 seconds
async void CheckWeather()
{
var weather = await GetWeather();
//do something with the weather now you have it
}
async Task<WeatherResult> GetWeather()
{
var weatherJson = await CallToNetworkAddressToGetWeather();
return deserializeJson<weatherJson>(weatherJson);
}
//SYNCHRONOUS
//This method is called whenever the screen is pressed
void ScreenPressed()
{
DrawSketchOnScreen();
}
Для быстрого обучения..
как и когда использовать <удар>
async
иждут
</удара>задачи
? Потому что обучение задачи автоматически распространяется и на другие 2. Ради обучения, по крайней мере. Конечно, это ответ на ваш вопрос оasync
иждут
. Быстро пройти через синтаксис сахара: 5 минут
Мы 'в ожидании' задача должна быть завершена. Отсюда и
ждут. Так как мы используем ждут, мы должны использовать async(обязательные) и MethodAsync с 'асинхронные' в качестве префикса стандарт (кодирование). Дальнейшее чтение на потом [здесь][3] **Доля путаницы разработчик: 5 минут** Разработчик сделал ошибку, не выполнение задания, но он все еще работает! Постарайтесь понять вопрос и просто принято отвечать [приведенные здесь][4]. Надеюсь, что вы прочитали и полностью поняли. Также в нашем примере вызов уже построил MethodAsync () - это гораздо проще, чем реализация этого метода с
задач(
MethodTask ()), себя. Большинство разработчиков найти его трудно получить свою голову вокруг
задачипри преобразовании кода в асинхронный. Совет: попробуйте найти существующий асинхронного выполнения (например,
MethodAsyncили
ToListAsync`) на аутсорсинг трудности. Так что нам нужно только разобраться с async и await (который прост и очень похож на обычный код)
Проблема: быстро изменить реальное воплощение нормального кода
Асинхронной операции: 2 мин
Строки кода, показанного ниже в слой данных начали ломать(во многих местах). Потому что мы обновили некоторые кода .Net на 4.2 чтобы .Чистые ядра. Мы должны были исправить это в 1 час по всей приложение! var myContract = query.Where(c => c.ContractID == _contractID).First();
easypeasy!
var myContract = await query.Where(c => c.ContractID == _contractID).FirstAsync();
GetContract контракта(инт contractnumber)
для
асинхронные задачу<контракт> GetContractAsync(инт contractnumber)
GetContractAsync(123456);
называлась GetContractAsync(123456).Результата;
На более высоком уровне:
ключевое слово async позволяет ожидать и что's все, что он делает. Ключевое слово async не запустить метод в отдельном потоке. Начало Ф асинхронный метод выполняется синхронно, пока не достигнет ждут на трудоемкой задачей.
Вы можете ожидать от метода, который возвращает Task или Task типа T. вы не можете ждать на асинхронных Void метод.
в момент встречи главный поток ждет на трудоемкие задания или когда работа началась, основной поток вызывающего абонента текущего метода.
Если основной поток видит, ждут на задание, которое по-прежнему выполняется, это вовсе'т ждать его и возвращает вызывающей текущего метода. Таким образом, приложение остается отзывчивым.
5 ждут) на задания, теперь будет выполняться в отдельном потоке из пула потоков.
Ниже приведен пример кода. Выполните его и проверьте идентификатор потока
using System;
using System.Threading;
using System.Threading.Tasks;
namespace AsyncAwaitDemo
{
class Program
{
public static async void AsynchronousOperation()
{
Console.WriteLine("Inside AsynchronousOperation Before AsyncMethod, Thread Id: " + Thread.CurrentThread.ManagedThreadId);
//Task<int> _task = AsyncMethod();
int count = await AsyncMethod();
Console.WriteLine("Inside AsynchronousOperation After AsyncMethod Before Await, Thread Id: " + Thread.CurrentThread.ManagedThreadId);
//int count = await _task;
Console.WriteLine("Inside AsynchronousOperation After AsyncMethod After Await Before DependentMethod, Thread Id: " + Thread.CurrentThread.ManagedThreadId);
DependentMethod(count);
Console.WriteLine("Inside AsynchronousOperation After AsyncMethod After Await After DependentMethod, Thread Id: " + Thread.CurrentThread.ManagedThreadId);
}
public static async Task<int> AsyncMethod()
{
Console.WriteLine("Inside AsyncMethod, Thread Id: " + Thread.CurrentThread.ManagedThreadId);
int count = 0;
await Task.Run(() =>
{
Console.WriteLine("Executing a long running task which takes 10 seconds to complete, Thread Id: " + Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(20000);
count = 10;
});
Console.WriteLine("Completed AsyncMethod, Thread Id: " + Thread.CurrentThread.ManagedThreadId);
return count;
}
public static void DependentMethod(int count)
{
Console.WriteLine("Inside DependentMethod, Thread Id: " + Thread.CurrentThread.ManagedThreadId + ". Total count is " + count);
}
static void Main(string[] args)
{
Console.WriteLine("Started Main method, Thread Id: " + Thread.CurrentThread.ManagedThreadId);
AsynchronousOperation();
Console.WriteLine("Completed Main method, Thread Id: " + Thread.CurrentThread.ManagedThreadId);
Console.ReadKey();
}
}
}
public static void Main(string[] args)
{
string result = DownloadContentAsync().Result;
Console.ReadKey();
}
// You use the async keyword to mark a method for asynchronous operations.
// The "async" modifier simply starts synchronously the current thread.
// What it does is enable the method to be split into multiple pieces.
// The boundaries of these pieces are marked with the await keyword.
public static async Task<string> DownloadContentAsync()// By convention, the method name ends with "Async
{
using (HttpClient client = new HttpClient())
{
// When you use the await keyword, the compiler generates the code that checks if the asynchronous operation is finished.
// If it is already finished, the method continues to run synchronously.
// If not completed, the state machine will connect a continuation method that must be executed WHEN the Task is completed.
// Http request example.
// (In this example I can set the milliseconds after "sleep=")
String result = await client.GetStringAsync("http://httpstat.us/200?sleep=1000");
Console.WriteLine(result);
// After completing the result response, the state machine will continue to synchronously execute the other processes.
return result;
}
}
Кстати как я понимаю тоже, там должен быть третий срок присовокупить: "задачей".
"Асинхронный" - это просто классификатором, вы положили на свой способ сказать Это'ы асинхронный метод.
"Задачей" возвращение функции "асинхронный". Он выполняется асинхронно.
Вы ждут` задачи. Когда выполнение кода доходит до этой линии, управление переходит обратно к вызывающему окружающие исходной функции.
Если вместо этого вы назначаете возвращение "асинхронный" функции (т. е. задачи) переменной, когда выполнение кода доходит до этой линии, это просто продолжает за линию в функции а в задач
выполняется асинхронно.
> есть используя их равными для создания фоновых потоков для выполнения длинных
По логике продолжительности?
В этой статье MDSN:асинхронное программирование с использованием ключевых слов async и await (C#и c#) ясно объясняет это:
async и await ключевые слова Дон'т вызвать дополнительных потоков создан. Асинхронные методы Дон'т требуют многопоточности, поскольку асинхронный способ не'т выполняется в своем собственном потоке. Метод работает на текущем В контексте синхронизации и использует время на потоке, только когда метод активного.
В следующем коде метод HttpClient GetByteArrayAsync возвращает задачу<байт[]>, getContentsTask. Задача заключается в обещании произвести фактический массив байтов, когда задача будет завершена. Оператор await применяется для getContentsTask приостановить исполнение в SumPageSizesAsync до getContentsTask завершения. В то же время управление возвращается в вызывающую SumPageSizesAsync. Когда getContentsTask закончен, ждут выражения в массив байтов.
private async Task SumPageSizesAsync()
{
// To use the HttpClient type in desktop apps, you must include a using directive and add a
// reference for the System.Net.Http namespace.
HttpClient client = new HttpClient();
// . . .
Task<byte[]> getContentsTask = client.GetByteArrayAsync(url);
byte[] urlContents = await getContentsTask;
// Equivalently, now that you see how it works, you can write the same thing in a single line.
//byte[] urlContents = await client.GetByteArrayAsync(url);
// . . .
}
Ответы здесь полезны как общие рекомендации ждут/асинхронности. Они также содержат некоторые подробности о том, как ждут/асинхронный проводной. Мне бы хотелось поделиться некоторым практическим опытом с вами, что вы должны знать перед использованием этого шаблона.
Термин-то "ждут" это буквальное, так чего-нить вы это называете, будет ждать результата метода, прежде чем продолжить. На изображения нить, это катастрофа. Нить переднем плане несет бремя построения вашего приложения, включая представления, модели представления, начальной анимации, а что еще у вас есть загрузочный привязали с этими элементами. Поэтому, когда вас ждут поток изображения, вы стоп приложение. Пользователей ждет и ждет, когда ничего не происходит. Это создает негативный пользовательский опыт.
Можно, конечно, ждут фоновом потоке, используя различные средства:
Device.BeginInvokeOnMainThread(async () => { await AnyAwaitableMethod(); });
// Notice that we do not await the following call,
// as that would tie it to the foreground thread.
try
{
Task.Run(async () => { await AnyAwaitableMethod(); });
}
catch
{}
Полный код для этих и подобных им замечаний на https://github.com/marcusts/xamarin-forms-annoyances. Смотрите решение под названием AwaitAsyncAntipattern.СЛН.
На сайте GitHub также даны ссылки на более подробное обсуждение на эту тему.