任何人都可以解释什么 await 功能呢?

有帮助吗?

解决方案

他们只是谈到了这一点,在PDC 昨天!

等待以与在.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();

其他提示

基本上,asyncawait关键字允许你指定一个方法的执行应在await的所有用途,这标志着异步方法调用停止,然后恢复一旦异步操作完成。这使您可以异步调用的方法在应用程序的主线程和处理复杂的工作,而无需显式定义主题,并加入或阻止应用程序的主线程。

把它看成是有点类似于一个yield return语句生产一个IEnumerable的方法。当运行时击中yield,它基本上会保存方法的当前状态,并返回所得到的值或引用。下一次IEnumerator.MoveNext()被调用返回的对象(这是由运行时内部产生的)上,该方法的老状态恢复到堆栈和执行与yield return的下一行继续,如同我们从未离开方法。如果没有这个关键字,一个IEnumerator类型必须自定义的存储状态,并且处理迭代的请求,与方法,可以变得非常复杂确实

类似地,标记为async的方法必须具有至少一个await。在一个await,运行时将保存当前线程的状态和调用堆栈,使异步调用,身心恢复运行的消息循环处理的下一条消息,并保持该应用程序响应。当异步操作完成时,在下一调度时机,调用堆栈向上到异步操作中被推回,并继续,就好像呼叫是同步的。

因此,这两个新的关键字基本上简化异步处理的编码,很像yield return简化定制可枚举的产生。一对夫妇关键字和一点背景知识,你可以跳过传统的异步模式的所有混乱,往往容易出错的细节。这将是非常宝贵在非常喜欢的Winforms任何事件驱动GUI的应用程序,的Silverlight WPF。

目前公认的答案是误导。 await没有暂停任何东西。 首先,它只能在标记为async和返回Taskvoid方法或lambda表达式中使用,如果你不小心在有这种方法运行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()");
    }
}

输出:

  

进入的DoWork()。睡3个结果   异步任务迭代0点击   任务状态:WaitingForActivation结果   等待ENTER结果   异步任务迭代1结果   异步任务迭代2结果   异步任务迭代3结果   异步任务迭代4点击   异步任务迭代5点击   异步任务迭代6点击   异步任务迭代7结果   异步任务迭代8次点击   异步任务迭代9点击   离开的DoWork()

对于任何新的异步编程。网,这是一(完全假)的比喻,在一个场景你可能更熟悉-阿贾克斯的电话使用JavaScript/!一个简单的jQuery阿贾克斯后看起来是这样的:

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

我们之所以过程的结果在回呼功能是所以我们不阻止当前线,同时等待阿贾克斯呼吁的回报。只有当的响应已准备好将回调得到射击,释放前线去做其他的事情的平均时间。

现在,如果JavaScript支持 await 关键词(其当然,这并不(还没有!)),可以同样实现这一点:

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

这是一个很大的吸尘器,但它确实看起来我们介绍了同步,阻挡的代码。但是(假)JavaScript编译器,将采取一切之后 await 并且把它变成一个回调,这样在运行的第二次例会表现得就像第一次。

它可能看起来不像是你节省很多工作,但是当它涉及到的东西喜欢的例外处理和同步的情况下,编译器实际上是做一个 很多 的繁重你。欲了解更多,我会推荐的 常见问题解答 随后通过 斯蒂芬*克利里的博客串.

如果我必须实现它在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