Вопрос

Кто-нибудь может объяснить, что await Функция делает?

Это было полезно?

Решение

Они просто говорил об этом в PDC вчера!

Await используется в сочетании с задачами (параллельное программирование) в .NET. Это ключевое слово, вводимое в следующей версии .NET. Это более или менее позволяет вам «приостановить» выполнение метода ожидания задачи завершить выполнение. Вот краткий пример:

//create and run a new task  
Task<DataTable> dataTask = new Task<DataTable>(SomeCrazyDatabaseOperation);

//run some other code immediately after this task is started and running  
ShowLoaderControl();  
StartStoryboard();

//this will actually "pause" the code execution until the task completes.  It doesn't lock the thread, but rather waits for the result, similar to an async callback  
// please so also note, that the task needs to be started before it can be awaited. Otherwise it will never return
dataTask.Start();
DataTable table = await dataTask;

//Now we can perform operations on the Task result, as if we're executing code after the async operation completed  
listBoxControl.DataContext = table;  
StopStoryboard();  
HideLoaderControl();

Другие советы

В основном async и await Ключевые слова позволяют указать, что выполнение метода должно останавливаться на всех использования await, который отмечает вызовы асинхронного метода, а затем возобновляют после завершения асинхронной операции. Это позволяет вызывать метод в основной резьбе приложения и обрабатывать сложные работы асинхронно, без необходимости явных определять нити и присоединиться или блокировать основной нить приложения.

Думать об этом как о чем-то похоже на yield return Заявление в способе, продуцирующем IENumerable. Когда время выполнения попадает в yield, он будет в основном сохранить текущее состояние метода и возвращает стоимость или передачу отложений. В следующий раз, когда iEnumerator.movenext () вызывается на объекте возврата (который генерируется внутренне по времени выполнения), старое состояние метода восстанавливается в стек и выполнение продолжается с следующей строкой после yield return Как будто мы никогда не оставили метод. Без этого ключевого слова типа IEnumerator должны быть на заказ, определенные для хранения состояния и обрабатывают запросы итерации, с методами, которые действительно могут стать очень сложными.

Аналогично, метод, помеченный как async Должен иметь хотя бы один await. Отказ На await, время выполнения будет сохранять состояние текущего потока и стека вызовов, сделать асинхронный вызов и расслабиться обратно к цикле сообщений выполнения, чтобы обрабатывать следующее сообщение и сохранить адаптацию приложения. Когда асинхронная операция завершена, при следующей возможности планирования стек вызовов в управление Async нажимается назад и продолжается, как если бы вызов был синхронным.

Итак, эти два новых ключевых слова в основном упрощают кодирование асинхронных процессов, как yield return упростил генерацию пользовательских перечисленных лиц. С парой ключевых слов и небольшим фоновым знанием вы можете пропустить все запутанные и часто подверженные ошибкам детали традиционного асинхронного рисунка. Это будет неоценимо в значительной степени любого приложения GUI, управляемого событиями, как WinForms, WPF Silverlight.

В настоящее время принятый ответ вводит в заблуждение.await не паузает ничего. Прежде всего, его можно использовать только в методах или лямбдасе, помеченных как async и возвращение Task или void Если вам все равно Task Экземпляр работает в этом методе.

Вот иллюстрация:

internal class Program
{
    private static void Main(string[] args)
    {
        var task = DoWork();
        Console.WriteLine("Task status: " + task.Status);
        Console.WriteLine("Waiting for ENTER");
        Console.ReadLine();
    }

    private static async Task DoWork()
    {
        Console.WriteLine("Entered DoWork(). Sleeping 3");
        // imitating time consuming code
        // in a real-world app this should be inside task, 
        // so method returns fast
        Thread.Sleep(3000);

        await Task.Run(() =>
            {
                for (int i = 0; i < 10; i++)
                {
                    Console.WriteLine("async task iteration " + i);
                    // imitating time consuming code
                    Thread.Sleep(1000);
                }
            });

        Console.WriteLine("Exiting DoWork()");
    }
}

Выход:

Вошел в дшерк (). Спать 3
асинхронная итерация задачи 0
Статус задачи: anogneractivation
Ожидание ввода
Итерация асинхронизации 1
асинхронная задача итерация 2
асинхронная задача итерация 3
асинхронная задача итерация 4
асинхронная задача итерация 5
асинхронная задача итерация 6
асинхронная задача итерация 7
асинхронная задача итерация 8
асинхронная задача итерация 9
Выход в доноке ()

Для любого нового к асинхронному программированию в .NET, вот (полностью подделка) аналогии в сценарии, с которыми вы можете быть более знакомы - ajax звонки, используя JavaScript / jQuery. Простое сообщение jQuery ajax выглядит так:

$.post(url, values, function(data) {
  // AJAX call completed, do something with returned data here
});

Причина, по которой мы обрабатываем результаты в функции обратного вызова, это поэтому мы не блокируем текущий поток при ожидании возврата Call ajax. Только когда ответ будет готов, будет уволен обратный вызов, освобождая текущий поток, чтобы делать другие вещи в среднем время.

Теперь, если JavaScript поддерживал await Ключевое слово (которое, конечно, не так (все же!)), вы можете достичь того же с этим:

var data = await $.post(url, values);
// AJAX call completed, do something with returned data here

Это намного очиститель, но это, похоже, мы ввели синхронный, блокирующий код. Но (поддельный) компилятор JavaScript сделал бы все после await И проводят его в обратный вызов, поэтому во время выполнения второй пример будет вести себя так же, как первый.

Это может показаться не так, как будто это экономит вам много работы, но когда дело доходит до вещей, таких как контекста обработки исключений и синхронизации, компилятор на самом деле делает много тяжелого подъема для вас. Для большего, я бы порекомендовал Часто задаваемые вопросы с последующим Стивен Culy's Blog Series.

Если бы мне пришлось реализовать его в Java, это будет выглядеть так, как это так:

/**
 * @author Ilya Gazman
 */
public abstract class SynchronizedTask{

    private ArrayList<Runnable> listeners = new ArrayList<Runnable>();

    private static final ThreadPoolExecutor threadPoolExecutor =  new ThreadPoolExecutor(6, 6, 0, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(1000));

    public final void await(Runnable listener){
        synchronized (this) {
            listeners.add(listener);
        }
    }

    public void excecute(){
        onExcecute();
        for (int i = listeners.size() - 1; i >= 0; i--) {
            Runnable runnable;
            synchronized (this) {
                runnable = listeners.remove(i);
            }
            threadPoolExecutor.execute(runnable);
        }
    }

    protected abstract void onExcecute();
}

Ваше приложение будет использовать это так:

public class Test{
    private Job job = new Job();

    public Test() {
        craeteSomeJobToRunInBackground();
        methode1();
        methode2();
    }

    private void methode1(){
        System.out.println("Running methode 1");
        job.await(new Runnable() {

            @Override
            public void run() {
                System.out.println("Continue to running methode 1");
            }
        });
    }

    private void methode2(){
        System.out.println("Running methode 2");
    }

    private void craeteSomeJobToRunInBackground() {
        new Thread(new Runnable() {

            @Override
            public void run() {
                job.excecute();
            }
        }).start();
    }

    private class Job extends SynchronizedTask{

        @Override
        protected void onExcecute() {
            try {
                Thread.sleep(1000);
            }
            catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("Job is done");
        }
    }
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top