programing tip

새로운 C # await 기능은 무엇을합니까?

itbloger 2020. 9. 25. 07:37
반응형

새로운 C # await 기능은 무엇을합니까? [닫은]


누구든지 그 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();

기본적으로 asyncawait키워드를 사용하면 메서드 실행이의 모든 사용에서 중지되도록 지정하여 await비동기 메서드 호출을 표시 한 다음 비동기 작업이 완료되면 다시 시작할 수 있습니다. 이를 통해 앱의 기본 스레드에서 메서드를 호출하고 스레드 및 조인을 명시 적으로 정의하거나 앱의 기본 스레드를 차단할 필요없이 복잡한 작업을 비동기 적으로 처리 할 수 ​​있습니다.

yield returnIEnumerable을 생성하는 메서드 문과 다소 유사하다고 생각하십시오 . 런타임이에 도달 yield하면 기본적으로 메서드의 현재 상태를 저장하고 산출되는 값 또는 참조를 반환합니다. 다음에 IEnumerator.MoveNext ()가 반환 객체 (런타임에 의해 내부적으로 생성됨)에서 호출되면 메서드의 이전 상태가 스택에 복원되고 다음 행에서 실행이 계속됩니다 yield return. 방법. 이 키워드가 없으면 IEnumerator 유형은 상태를 저장하고 반복 요청을 처리하기 위해 사용자 정의해야합니다. 메서드는 실제로 매우 복잡해질 수 있습니다.

마찬가지로,로 표시하는 방법은 async적어도 하나 있어야 await. await, 현재의 thread의 상태와 호출 스택을 절약 할 수 런타임은, 비동기 호출, 다음 메시지를 처리하고 응답 응용 프로그램을 유지하는 런타임의 메시지 루프에 풀림 등을 확인합니다. 비동기 작업이 완료되면 다음 예약 기회에 비동기 작업을위한 호출 스택이 다시 푸시되고 호출이 동기식 인 것처럼 계속됩니다.

따라서이 두 가지 새로운 키워드는 기본적으로 yield return사용자 정의 열거 형 생성을 단순화 한 것처럼 비동기 프로세스의 코딩을 단순화합니다. 몇 가지 키워드와 약간의 배경 지식 만 있으면 기존 비동기 패턴의 혼란스럽고 종종 오류가 발생하기 쉬운 세부 정보를 모두 건너 뛸 수 있습니다. 이는 Silverlight의 WPF 인 Winforms와 같은 거의 모든 이벤트 기반 GUI 앱에서 매우 유용 할 것입니다.


현재 허용되는 답변은 오해의 소지가 있습니다. 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()");
    }
}

산출:

Entered DoWork(). Sleeping 3
async task iteration 0
Task status: WaitingForActivation
Waiting for ENTER
async task iteration 1
async task iteration 2
async task iteration 3
async task iteration 4
async task iteration 5
async task iteration 6
async task iteration 7
async task iteration 8
async task iteration 9
Exiting DoWork()


For anyone new to asynchronous programming in .NET, here's a (totally fake) analogy in a scenario you may be more familiar with - AJAX calls using JavaScript/jQuery. A simple jQuery AJAX post looks like this:

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

The reason we process the results in a callback function is so we don't block the current thread while waiting for the AJAX call to return. Only when the response is ready will the callback get fired, freeing the current thread to do other things in the mean time.

Now, if JavaScript supported the await keyword (which of course it doesn't (yet!)), you could achieve the same with this:

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

That's a lot cleaner, but it sure looks like we introduced synchronous, blocking code. But the (fake) JavaScript compiler would have taken everything after await and wired it into a callback, so at runtime the second example would behave just like the first.

It may not seem like it's saving you much work, but when it comes to things like exception handling and synchronization contexts, the compiler is actually doing a lot of heavy lifting for you. For more, I'd recommend the FAQs followed by Stephen Cleary's blog series.


If I had to implement it in Java it would look some thing like this:

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

Your application would use it like this:

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

참고URL : https://stackoverflow.com/questions/4057359/whats-the-new-c-sharp-await-feature-do

반응형