Vra

Kan iemand verduidelik wat die await funksie doen?

Was dit nuttig?

Oplossing

Hulle het net gepraat oor hierdie by PDC gister!

Wag gebruik in samewerking met Take (parallel programmering) in NET. Dit is 'n navraag bekendgestel in die volgende weergawe van NET. Dit meer of minder kan jy "breek" die uitvoering van 'n metode om te wag vir die taak om volledige uitvoering. Hier is 'n kort voorbeeld:

//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();

Ander wenke

Eintlik is die async en await sleutelwoorde kan jy dit uitvoering van 'n metode spesifiseer moet stop by al gebruike van await, wat asynchrone metode oproepe te merk, en dan hervat sodra die asynchrone operasie is voltooi. Dit laat jou toe om 'n metode asynchroon noem in hoof draad 'n app en hanteer komplekse werk, sonder die behoefte om drade uitdruklik definieer en sluit aan by of blokkeer belangrikste draad die jeug se.

Dink aan dit as 'n bietjie soortgelyk aan 'n yield return verklaring in 'n metode vervaardiging van 'n IEnumerable. Wanneer die runtime treffers die yield, sal dit basies red huidige stand van die metode se en die standaard van die waarde of verwysing wat opgelewer. Die volgende keer IEnumerator.MoveNext () is 'n beroep op die terugkeer voorwerp (wat intern gegenereer word deur die runtime), is ou staat die metode se herstel na die stapel en uitvoering gaan voort met die volgende lyn na die yield return asof ons nooit sal verlaat die metode. Sonder hierdie navraag, 'n IEnumerator tipe moet persoonlike gedefinieerde om winkel staat en hanteer die iterasie versoeke, met metodes wat baie kompleks, want dit kan raak.

Net so 'n metode gemerk as async moet ten minste een await het. Op 'n await, die runtime sal die huidige draad se toestand en oproep stapel te red, maak die asynchrone oproep, en ontspan terug na die runtime se boodskap lus om die volgende boodskap te hanteer en die jeug reageer hou. Wanneer die asynchrone operasie is voltooi, by die volgende skedulering geleentheid, is die oproep stapel te die asinkroniseer operasie terug gestoot in en voortgegaan asof die oproep was sinchrone.

So, hierdie twee nuwe sleutelwoorde basies vereenvoudig die kodering van asynchrone prosesse, baie soos yield return vereenvoudig die geslag van persoonlike enumerables. Met 'n paar sleutelwoorde en 'n bietjie agtergrond kennis, kan jy al die verwarrend en dikwels fout sensitiewe besonderhede van 'n tradisionele asynchrone patroon slaan. Dit sal van onskatbare waarde wees in pretty much enige gebeurtenis gedrewe GUI inligting soos Winforms, WPF van Silver.

Die oomblik aanvaar antwoord is misleidend. await is niks pousering. In die eerste plek kan dit slegs gebruik word in metodes of lambdas gemerk as async en terugkeer Task of void as jy nie omgee om Task byvoorbeeld hardloop in hierdie metode.

Hier is 'n illustrasie:

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()");
    }
}

Uitgawe:

  

Aangegaan DoWork (). Slaap 3
  asinkroniseer taak iterasie 0
  Taak status: WaitingForActivation
  Wag vir Enter
  asinkroniseer taak iterasie 1
  asinkroniseer taak iterasie 2
  asinkroniseer taak iterasie 3
  asinkroniseer taak iterasie 4
  asinkroniseer taak iterasie 5
  asinkroniseer taak iterasie 6
  asinkroniseer taak iterasie 7
  asinkroniseer taak iterasie 8
  asinkroniseer taak iterasie 9
  Verlaat DoWork ()

Vir iemand nuut in asynchrone ontwikkeling in NET, hier is 'n (heeltemal vals) analogie in 'n scenario wat jy kan meer vertroud wees met - AJAX oproepe met behulp van JavaScript / jQuery. 'N Eenvoudige jQuery AJAX post lyk soos volg:

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

Die rede waarom ons die resultate in 'n terugbel funksie verwerk is, sodat ons nie die huidige draad te sluit terwyl hulle wag vir die AJAX oproep tot terugkeer. Net vir die reaksie is gereed sal die callback kry afgevuur, bevry die huidige draad om ander dinge te doen in die mean time.

Nou, as JavaScript ondersteun die await navraag (wat natuurlik dit nie gebeur nie ( nog )), kan jy dieselfde bereik met hierdie:

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

Dit is 'n baie skoner, maar dit seker lyk asof ons bekendgestel sinchrone, blokkeer kode. Maar die (valse) JavaScript samesteller sal alles na await geneem en bedraad dit in 'n terugbel, so tydens looptyd die tweede voorbeeld sou optree net soos die eerste.

Dit mag nie lyk soos dit spaar jy baie werk, maar wanneer dit kom by dinge soos om uitsonderings te hanteer en sinchronisasie konteks, is die samesteller eintlik 'n lot van swaar werk vir jou. Vir meer, wil ek aanbeveel die FAQs gevolg deur Stephen Cleary se blog reeks .

As ek moes dit te implementeer in Java dit sou 'n ding soos volg lyk:

/**
 * @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();
}

Jou aansoek sal dit gebruik soos volg:

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");
        }
    }
}
Gelisensieer onder: CC-BY-SA met toeskrywing
Nie verbonde aan StackOverflow
scroll top