program story

Entity Framework SaveChanges () 대 SaveChangesAsync () 및 Find () 대 FindAsync ()

inputbox 2020. 10. 29. 08:06
반응형

Entity Framework SaveChanges () 대 SaveChangesAsync () 및 Find () 대 FindAsync ()


나는 위의 두 쌍의 차이점을 찾고 있었지만 그것에 대해 명확하게 설명하는 기사와 둘 중 하나를 사용해야 할 때를 찾지 못했습니다.

그래서 차이 무엇 SaveChanges()SaveChangesAsync()?
그리고 사이 Find()FindAsync()?

서버 측에서 Async메서드 를 사용할 때 await. 따라서 나는 그것이 서버 측에서 비동기 적이라고 생각하지 않습니다.

클라이언트 측 브라우저에서 UI 차단을 방지하는 데만 도움이됩니까? 아니면 그들 사이에 장단점이 있습니까?


원격 서버에서 작업을 수행해야 할 때마다 프로그램은 요청을 생성하고 전송 한 다음 응답을 기다립니다. 내가 사용 SaveChanges()하고 SaveChangesAsync()예로하지만 같은 적용 Find()하고 FindAsync().

myList데이터베이스에 추가해야하는 100 개 이상의 항목 목록이 있다고 가정 해 보겠습니다 . 이를 삽입하려면 함수는 다음과 같습니다.

using(var context = new MyEDM())
{
    context.MyTable.AddRange(myList);
    context.SaveChanges();
}

먼저의 인스턴스를 만들고 테이블에 MyEDM목록 myList추가 MyTable한 다음을 호출 SaveChanges()하여 변경 사항을 데이터베이스에 유지합니다. 원하는 방식으로 작동하고 레코드가 커밋되지만 커밋이 완료 될 때까지 프로그램은 다른 작업을 수행 할 수 없습니다. 커밋하는 내용에 따라 시간이 오래 걸릴 수 있습니다. 레코드에 대한 변경 사항을 커밋하는 경우 엔터티는 한 번에 하나씩 커밋해야합니다 (업데이트를 위해 저장하는 데 2 ​​분이 걸렸습니다)!

이 문제를 해결하려면 두 가지 중 하나를 수행 할 수 있습니다. 첫 번째는 삽입을 처리하기 위해 새 스레드를 시작할 수 있다는 것입니다. 이렇게하면 계속 실행하기 위해 호출 스레드가 해제되지만 거기에 앉아 대기 할 새 스레드를 만들었습니다. 그 오버 헤드가 필요 없으며 이것이 async await패턴이 해결하는 것입니다.

I / O 작업의 경우 await빠르게 가장 친한 친구가됩니다. 위에서 코드 섹션을 취하면 다음과 같이 수정할 수 있습니다.

using(var context = new MyEDM())
{
    Console.WriteLine("Save Starting");
    context.MyTable.AddRange(myList);
    await context.SaveChangesAsync();
    Console.WriteLine("Save Complete");
}

아주 작은 변화이지만 코드의 효율성과 성능에 큰 영향을 미칩니다. 그래서 어떻게 되나요? 코드의 시작은 당신의 인스턴스를 생성, 동일 MyEDM하고 추가 myList로를 MyTable. 그러나를 호출하면 await context.SaveChangesAsync()코드 실행이 호출 함수로 돌아갑니다! 따라서 모든 레코드가 커밋되기를 기다리는 동안 코드가 계속 실행될 수 있습니다. 위의 코드가 포함 된 함수에 서명이 있다고 가정하면 public async Task SaveRecords(List<MyTable> saveList)호출 함수는 다음과 같습니다.

public async Task MyCallingFunction()
{
    Console.WriteLine("Function Starting");
    Task saveTask = SaveRecords(GenerateNewRecords());

    for(int i = 0; i < 1000; i++){
        Console.WriteLine("Continuing to execute!");
    }

    await saveTask;
    Console.Log("Function Complete");
}

왜 이런 기능이 있는지 모르겠지만 출력되는 내용은 어떻게 async await작동 하는지 보여줍니다 . 먼저 무슨 일이 일어나는지 살펴 보겠습니다.

실행은 입력 MyCallingFunction, Function Starting다음, Save Starting다음 함수가 콘솔에 기록됩니다 SaveChangesAsync()호출됩니다. 이 시점에서 실행은 MyCallingFunction최대 1000 회까지 'Continuing to Execute'를 쓰는 for 루프로 돌아가서 들어갑니다. SaveChangesAsync()받는 완료, 실행 돌아 SaveRecords작성 기능, Save Complete콘솔에. 모든 것이 SaveRecords완료 되면 완료 MyCallingFunction되었을 때 실행이 계속됩니다 SaveChangesAsync(). 혼란스러워? 다음은 출력 예입니다.

기능 시작
저장 시작
계속 실행합니다!
계속 실행합니다!
계속 실행합니다!
계속 실행합니다!
계속 실행합니다!
....
계속 실행합니다!
저장 완료!
계속 실행합니다!
계속 실행합니다!
계속 실행합니다!
....
계속 실행합니다!
기능 완료!

아니면 :

기능 시작
저장 시작
계속 실행합니다!
계속 실행합니다!
저장 완료!
계속 실행합니다!
계속 실행합니다!
계속 실행합니다!
....
계속 실행합니다!
기능 완료!

That is the beauty of async await, your code can continue to run while you are waiting for something to finish. In reality, you would have a function more like this as your calling function:

public async Task MyCallingFunction()
{
    List<Task> myTasks = new List<Task>();
    myTasks.Add(SaveRecords(GenerateNewRecords()));
    myTasks.Add(SaveRecords2(GenerateNewRecords2()));
    myTasks.Add(SaveRecords3(GenerateNewRecords3()));
    myTasks.Add(SaveRecords4(GenerateNewRecords4()));

    await Task.WhenAll(myTasks.ToArray());
}

Here, you have four different save record functions going at the same time. MyCallingFunction will complete a lot faster using async await than if the individual SaveRecords functions were called in series.

The one thing that I have not touched on yet is the await keyword. What this does is stop the current function from executing until whatever Task you are awaiting completes. So in the case of the original MyCallingFunction, the line Function Complete will not be written to the console until the SaveRecords function finishes.

Long story short, if you have an option to use async await, you should as it will greatly increase the performance of your application.


This statement is incorrect:

On server side, when we use Async methods, we also need to add await.

You do not need to add "await". "await" is merely a convenient keyword in C# that enables you to write more lines of code after the call, and those other lines will only get executed after the Save operation completes. But as you pointed out, you could accomplish that simply by calling SaveChanges instead of SaveChangesAsync.

But fundamentally, an async call is about much more than that. The idea here is that if there is other work you can do (on the server) while the Save operation is in progress, then you should use SaveChangesAsync. Do not use "await". Just call SaveChangesAsync, and then continue to do other stuff in parallel. This includes potentially, in a web app, returning a response to the client even before the Save has completed. But of course, you still will want to check the final result of the Save so that in case it fails, you can communicate that to your user, or log it somehow.

참고URL : https://stackoverflow.com/questions/30042791/entity-framework-savechanges-vs-savechangesasync-and-find-vs-findasync

반응형