'async' 및 'wait'를 사용하는 방법 및 시기
제가 이해하기로는 코드를 쓰기 쉽고 읽기 쉽게 만드는 것이 주요 작업 중 하나입니다. 하지만 코드를 사용하는 것이 백그라운드 스레드를 생성하여 장시간 논리를 수행하는 것과 동일합니까?
저는 현재 가장 기본적인 예시를 시도하고 있습니다.제가 댓글을 몇 개 추가했습니다.당신이 그것을 명확히 해줄 수 있습니까?
// I don't understand why this method must be marked as `async`.
private async void button1_Click(object sender, EventArgs e)
{
Task<int> access = DoSomethingAsync();
// task independent stuff here
// this line is reached after the 5 seconds sleep from
// DoSomethingAsync() method. Shouldn't it be reached immediately?
int a = 1;
// from my understanding the waiting should be done here.
int x = await access;
}
async Task<int> DoSomethingAsync()
{
// is this executed on a background thread?
System.Threading.Thread.Sleep(5000);
return 1;
}
을 할 때async그리고.await컴파일러는 백그라운드에서 상태 시스템을 생성합니다.
다음은 현재 진행 중인 몇 가지 세부 사항을 설명할 수 있는 예입니다.
public async Task MyMethodAsync()
{
Task<int> longRunningTask = LongRunningOperationAsync();
// independent work which doesn't need the result of LongRunningOperationAsync can be done here
//and now we call await on the task
int result = await longRunningTask;
//use the result
Console.WriteLine(result);
}
public async Task<int> LongRunningOperationAsync() // assume we return an int from this long running operation
{
await Task.Delay(1000); // 1 second delay
return 1;
}
자, 그럼 여기서 무슨 일이 일어날까요?
Task<int> longRunningTask = LongRunningOperationAsync();하기 시작합니다.LongRunningOperation메인 스레드(스레드 ID = 1)에 대해 독립적인 작업이 수행되었다고 가정합니다.
await longRunningTask도달했습니다.에 자, 만에가
longRunningTask중입니다.MyMethodAsync()호출 메서드로 돌아가므로 주 스레드가 차단되지 않습니다. 때.longRunningTask스레드가 될 수 가 그면스모풀스레가(스일수있드음드다의니레레반됩)환러드로 돌아갑니다.MyMethodAsync()이전 컨텍스트에서 실행을 계속합니다(이 경우 결과를 콘솔에 인쇄).
두 번째 경우는 다음과 같습니다.longRunningTask이미 실행을 마쳤으며 결과를 사용할 수 있습니다.에 할 때await longRunningTask이미 결과가 있으므로 코드는 동일한 스레드에서 계속 실행됩니다.(이 경우 결과를 콘솔로 인쇄).물론 이것은 위의 예에 해당하지 않습니다. 위의 예에는 해당되지 않습니다.Task.Delay(1000)관련된.
제가 알기로는 비동기와 대기가 하는 주요 일 중 하나는 코드를 쓰기 쉽고 읽기 쉽게 만드는 것입니다.
그들은 비동기식 코드를 쓰기 쉽고 읽기 쉽게 하기 위한 것입니다.
장시간 논리를 수행하기 위해 백그라운드 스레드를 생성하는 것과 동일합니까?
천만에요.
나는 왜 이 방법이 '비동기화'로 표시되어야 하는지 이해할 수 없습니다.
그async는 키드를면하사를 합니다.await키워드그래서 어떤 방법을 사용하든await '표해야합다니시합다▁be'로 표시해야 합니다.async.
이 라인은 DoSomethingAsync() 메서드에서 5초 수면 후에 도달합니다.즉시 연락해야 하는 거 아닙니까?
아니요, 왜냐하면async메서드는 기본적으로 다른 스레드에서 실행되지 않습니다.
이것이 백그라운드 스레드에서 실행됩니까?
아니요.
제 await소개가 도움이 될 수도 있습니다.공식 MSDN 문서도 비정상적으로 우수합니다(특히 TAP 섹션).async팀은 훌륭한 FAQ를 발표했습니다.
설명.
에 다은의간예다입의 .async/await해야 할 사항이 더 .이 외에도 고려해야 할 세부 사항이 훨씬 더 많습니다.
참고:Task.Delay(1000)1초 동안 작업하는 것을 시뮬레이션합니다.이것은 외부 자원의 응답을 기다리는 것으로 생각하는 것이 가장 좋다고 생각합니다.코드가 응답을 기다리고 있기 때문에 시스템은 실행 중인 작업을 옆으로 설정하고 완료되면 다시 해당 작업으로 돌아올 수 있습니다.한편, 그 스레드에서 다른 작업을 수행할 수 있습니다.
아래 예제에서는 첫 번째 블록이 정확히 이 작업을 수행하고 있습니다.모든 작업이 즉시 시작됩니다.Task.Delay선)을 사용하여 측면으로 설정합니다.는 코가일중니다에서 됩니다.await a다음 라인으로 이동하기 전에 1초 지연이 완료될 때까지 라인을 선택합니다. 때부터b,c,d,그리고.e 거의 했습니다.a(대기 시간이 부족하기 때문에) 이 경우에는 거의 동시에 완료해야 합니다.
아래 예제에서 두 번째 블록은 작업을 시작하고 작업이 완료될 때까지 기다립니다.await다음 작업을 시작하기 전에 수행합니다.이 작업을 반복할 때마다 1초가 걸립니다. 그await프로그램을 일시 중지하고 계속하기 전에 결과를 기다리는 중입니다.이것이 첫 번째 블록과 두 번째 블록의 주요 차이점입니다.
예
Console.WriteLine(DateTime.Now);
// This block takes 1 second to run because all
// 5 tasks are running simultaneously
{
var a = Task.Delay(1000);
var b = Task.Delay(1000);
var c = Task.Delay(1000);
var d = Task.Delay(1000);
var e = Task.Delay(1000);
await a;
await b;
await c;
await d;
await e;
}
Console.WriteLine(DateTime.Now);
// This block takes 5 seconds to run because each "await"
// pauses the code until the task finishes
{
await Task.Delay(1000);
await Task.Delay(1000);
await Task.Delay(1000);
await Task.Delay(1000);
await Task.Delay(1000);
}
Console.WriteLine(DateTime.Now);
출력:
5/24/2017 2:22:50 PM
5/24/2017 2:22:51 PM (First block took 1 second)
5/24/2017 2:22:56 PM (Second block took 5 seconds)
동기화 컨텍스트에 대한 추가 정보
참고: 여기는 저에게 약간의 안개가 끼는 곳이므로, 제가 틀린 것이 있으면 수정해 주시면 답변을 업데이트하겠습니다.이 어떻게 한 수 .ConfigureAwait(false)최적화의 기회를 놓치게 될 것입니다.
이것의 한 가지 측면이 있습니다.async/await개념이 좀 더 이해하기 어렵습니다. 예에서 이 것이 같은 한 스레드로 보이는 것)에서 사실입니다.SynchronizationContext은 ) 입니다.await실행 중이던 원래 스레드의 동기화 컨텍스트를 복원합니다.예를 들어 ASP에 있습니다.은 당이가있는고 NET를 있습니다.HttpContext요청이 들어올 때 스레드에 연결됩니다.이 컨텍스트에는 언어, IP 주소, 헤더 등을 포함하는 원래 요청 개체와 같은 원래 Http 요청에 특정한 항목이 포함됩니다.이 무언가를, 에서 정보를 빼내려고 할 수도 있습니다.HttpContext문맥을 것이라는 것을 은 그것에 것을 할 수 .컨텍스트를 어떤 용도로도 사용하지 않을 것이라는 것을 알고 있다면, 컨텍스트에 대해 "관심 없음"을 선택할 수 있습니다.이렇게 하면 기본적으로 컨텍스트를 가져오지 않고 별도의 스레드에서 코드를 실행할 수 있습니다.
어떻게 이를 달성합니까? 적으로기본,,await a;코드는 실제로 컨텍스트를 캡처하고 복원하려는 경우를 가정합니다.
await a; //Same as the line below
await a.ConfigureAwait(true);
메인 코드가 원래 컨텍스트 없이 새 스레드에서 계속 진행되도록 하려면 true 대신 false를 사용하면 컨텍스트를 복원할 필요가 없음을 알 수 있습니다.
await a.ConfigureAwait(false);
프로그램이 일시 중지된 후에는 컨텍스트가 전혀 다른 스레드에서 프로그램이 계속됩니다.여기서 성능 향상이 가능합니다. 처음부터 원래 컨텍스트를 복원할 필요 없이 사용 가능한 모든 스레드에서 성능을 지속적으로 개선할 수 있습니다.
이 물건들이 헷갈리나요? 할 수 요?당신은 그것을 알아낼 수 있습니까?아마! , 일단의다념, 술으로는사, 더기있게경적에 대한 기술적인 이해가 있는 에게 더 이 있는 Stephen .async/await이미.
다른 답변에 대한 자세한 내용은 대기(C# 참조)를 참조하십시오.
그리고 더 구체적으로, 포함된 예에서, 그것은 당신의 상황을 약간 설명합니다.
다음 Windows Forms 예제에서는 비동기식 WaitAsynchlyAsync 메서드에서 waita를 사용하는 방법을 보여 줍니다.해당 메서드의 동작과 WaitSynchronously의 동작을 비교합니다.WaitSync는 작업에 대기 연산자를 적용하지 않으면 정의에 비동기식 수정자를 사용하고 스레드에 대한 호출에도 불구하고 동기식으로 실행됩니다.그것의 몸에서 잠을 잡니다.
private async void button1_Click(object sender, EventArgs e)
{
// Call the method that runs asynchronously.
string result = await WaitAsynchronouslyAsync();
// Call the method that runs synchronously.
//string result = await WaitSynchronously ();
// Display the result.
textBox1.Text += result;
}
// The following method runs asynchronously. The UI thread is not
// blocked during the delay. You can move or resize the Form1 window
// while Task.Delay is running.
public async Task<string> WaitAsynchronouslyAsync()
{
await Task.Delay(10000);
return "Finished";
}
// The following method runs synchronously, despite the use of async.
// You cannot move or resize the Form1 window while Thread.Sleep
// is running because the UI thread is blocked.
public async Task<string> WaitSynchronously()
{
// Add a using directive for System.Threading.
Thread.Sleep(10000);
return "Finished";
}
가장 빠른 학습을 위해..
방법 실행 흐름 이해(도표 포함): 3분
질문 자기소개 (술 배우기) : 1분
구문 분석 시간 단축: 5분
개발자의 혼란 공유: 5분
문제:실제 구현된 일반 코드를 비동기 코드로 신속하게 변경: 2분
다음 단계는 어디입니까?
방법 실행 흐름 이해(도표 포함): 3분
이 이미지에서는 #6에 초점을 맞춥니다(그 이상은 아닙니다).
#6 단계에서는 작업량이 부족하여 실행이 중지되었습니다.계속하려면 getStringTask(함수의 일종)의 결과가 필요합니다.그러므로, 그것은 다음을 사용합니다.await운영자가 진행을 중단하고 (우리가 진행 중인 이 방법의) 호출자에게 제어권을 돌려줍니다.getStringTask에 대한 실제 통화는 #2 이전에 이루어졌습니다.#2에서 문자열 결과를 반환하기로 약속했습니다.하지만 언제 결과가 돌아올까요? 그럴까요(#1:AccessTheWebAsync)에서 두 번째 전화를 다시 걸시겠습니까? #2(호출 진술서)와 #6(대기 진술서) 중 누가 결과를 얻습니까?
액세스의 외부 호출자WebAsync()도 지금 대기 중입니다.그래서 접속 대기 중인 발신자WebAsync 및 액세스WebAsync가 현재 GetStringAsync를 기다리고 있습니다.흥미로운 것은 액세스입니다.WebAsync는 대기 시간을 절약하기 위해 대기 전에 몇 가지 작업(#4)을 수행했습니다.외부 발신자(및 체인의 모든 발신자)에게도 동일한 멀티태스킹 자유가 제공되며, 이것이 바로 이 '비동기화'의 가장 큰 장점입니다!당신은 그것이 동기적이라고 느낍니다.아니면 평범하지만 그렇지 않습니다.
#2와 #6은 나누어져 있어서 #4(기다리는 동안 작업)의 장점이 있습니다.하지만 우리는 분열하지 않고도 그것을 할 수 있습니다.그래서 2위는 다음과 같습니다.string urlContents = await client.GetStringAsync("...");여기서 우리는 이점을 볼 수 없지만 체인의 어딘가에서 하나의 함수가 분할되는 반면 나머지 함수는 분할되지 않고 호출됩니다.체인에서 사용하는 함수/클래스에 따라 다릅니다.기능에서 기능으로의 이러한 행동 변화는 이 주제에 대해 가장 혼란스러운 부분입니다.
메서드가 이미 반환되었으므로(#2) 다시 반환할 수 없습니다(두 번째가 아님).그러면 전화를 건 사람은 어떻게 알까요?이것은 모두 작업에 관한 것입니다!작업이 반환되었습니다.작업 상태가 대기되었습니다(메소드도 값도 아님).작업에 값이 설정됩니다.작업 상태가 완료로 설정됩니다.호출자는 작업(#6)만 모니터링합니다. 따라서 6#은 결과를 어디서/누가 얻는지에 대한 답입니다.자세한 내용은 여기에서 확인하십시오.
학습을 위한 질문 자기소개: 1분
질문을 조금 조정해 보겠습니다.
사용 방법 및 시기
async그리고awaitTasks?
때문입니다.Task나머지 두 개를 자동으로 처리합니다(질문에 답변).
모든 아이디어는 매우 간단합니다.메소드는 모든 데이터 유형(더블, int, 객체 등)을 반환할 수 있지만 여기서는 이를 거부하고 강제로 'Task물체반환▁! 그래도 제외하지만 우리는 여전히 반환된 데이터(보이드 제외)가 필요하죠?그것은 내부의 표준 속성에 설정될 것입니다.Task eg:예: 'Result재산
구문 분석 시간 단축: 5분
- 원래 비비동기화 방법
internal static int Method(int arg0, int arg1) { int result = arg0 + arg1; IO(); // Do some long running IO. return result; }
- 위의 방법을 호출하는 완전히 새로운 태스크화된 방법
internal static Task<int> MethodTask(int arg0, int arg1) { Task<int> task = new Task<int>(() => Method(arg0, arg1)); task.Start(); // Hot task (started task) should always be returned. return task; }
대기 또는 비동기에 대해 언급했습니까?아닙니다. 위의 방법을 호출하면 모니터링할 수 있는 작업을 얻을 수 있습니다.태스크가 반환(또는 포함)하는 내용을 이미 알고 있습니다.정수
- 작업을 호출하는 것은 약간 까다로우며 이때 키워드가 나타나기 시작합니다.원래 메소드(비동기)를 호출하는 메소드가 있다면 아래와 같이 수정해야 합니다.메서드 작업()을 호출합니다.
internal static async Task<int> MethodAsync(int arg0, int arg1) { int result = await HelperMethods.MethodTask(arg0, arg1); return result; }
아래 이미지와 동일한 코드가 추가되었습니다.
- 우리는 일이 끝나기를 기다리고 있습니다. 그므로러로▁hence.
await(구문론) - wait를에 wait를 .
async(구문론) - 와 MethodAsync와
Async로 (사준용coding)))
await두 가지 (이해하기쉽두가지나지머지만▁(▁is가▁(지이)async,Async)는 :)이 아닐 수 있습니다.하지만 컴파일러에게는 훨씬 더 의미가 있을 것입니다.나중에 읽을 내용은 여기에 있습니다.
그래서 두 부분이 있습니다.
'작업' 생성(하나의 작업만 가능하며 추가적인 방법이 될 것입니다.)
작업을 호출할 구문 당을 만듭니다.
await+async메서드를 할 경우
기억하세요, 우리는 접속할 외부 발신자가 있었습니다.WebAsync()와 그 호출자도 살려둘 수 없습니다...즉, 동일한 것이 필요합니다.await+async또한. 그리고 그 사슬은 계속됩니다(따라서 이것은 많은 계층에 영향을 미칠 수 있는 파괴적인 변화입니다).원래의 방법은 아직 호출되지 않았기 때문에 중단되지 않은 변경으로 간주할 수도 있습니다.중단 변경을 적용하려면 액세스 권한을 변경하거나 삭제하고 작업 내부로 이동하면 클래스에서 작업 방법을 사용하도록 강제됩니다.어쨌든, 비동기식 통화에는 항상 다음이 있을 것입니다.Task한쪽 끝에만
좋아요, 하지만 한 개발자는 그것을 보고 놀랐습니다.Task누락...
개발자와 혼동을 공유: 5분
개발자가 구현하지 않는 실수를 범했습니다.Task하지만 여전히 작동합니다!여기에 제공된 질문과 수락된 답변을 이해하려고 합니다.당신이 읽고 완전히 이해하기를 바랍니다.요약하면 'Task'를 보거나 구현할 수는 없지만 상위/관련 클래스의 어딘가에서 구현된다는 것입니다.마찬가지로 우리의 예에서는 이미 작성된 것을 호출합니다.MethodAsync()그 방법을 구현하는 것보다 훨씬 쉽습니다.Task(MethodTask() 우리 우리 자신.대부분의 개발자들은 그들의 머리를 움직이는 것을 어려워합니다.Tasks코드를 비동기 코드로 변환하는 동안.
: " " " " ")을 찾습니다.MethodAsync또는ToListAsync 어려움을 아웃소싱합니다.따라서 비동기만 처리하고 기다리면 됩니다(일반 코드와 매우 유사하고 쉽고 쉽습니다).
문제:실제 구현된 일반 코드를 비동기식 작업으로 신속하게 변경: 2분
아래 데이터 계층에 표시된 코드 라인이 끊어지기 시작했습니다(많은 위치).에서 코드 일부를 업데이트했기 때문입니다.Net Framework 4.2.* to.넷코어.우리는 모든 애플리케이션에서 이것을 1시간 안에 고쳐야 했습니다!
var myContract = query.Where(c => c.ContractID == _contractID).First();
진정해요!
- EntityFramework 패키지에 QueryableEntityFramework 너겟이 되어 있기 했습니다.선번호내. 즉 을 하기 한 즉, 작기구(태스크)으로 수 .
Async그리고.await암호상 - 네임스페이스 = Microsoft.엔티티 프레임워크 코어
호출 코드 라인이 이렇게 변경되었습니다.
var myContract = await query.Where(c => c.ContractID == _contractID).FirstAsync();
- 메서드 서명이 변경되었습니다.
Contract GetContract(int contractnumber)
로.
async Task<Contract> GetContractAsync(int contractnumber)
- 영향을 . 호출방영받았습니다향을법.
GetContract(123456);라고 불렸습니다.GetContractAsync(123456).Result;
야!Result잘 잡았습니다! GetContractAsync는 " " " "만 합니다.Task우리가 원했던 가치가 아닙니다.Contract) 작업 결과를 사용할 수 있게 되면 해당 결과가 저장되고 이후에 해당 속성을 호출할 때 즉시 반환됩니다.유사한 'Wait()'을 사용하여 타임아웃 구현을 수행할 수도 있습니다.
시간 범위 = 시간 범위.밀리초(150)부터;
if(! t.Wait(ts) 콘솔.WriteLine("시간 초과 간격이 경과되었습니다.");
- 우리는 30분 만에 모든 곳에서 그것을 바꿨습니다!
그러나 설계자는 이것만을 위해 EntityFramework 라이브러리를 사용하지 말라고 했습니다!아뿔싸! 드라마!그런 다음 사용자 지정 작업 구현(yuk!)을 만들었습니다.당신도 알잖아요여전히 쉬워요! ..아직도 yuk..
다음 단계는 어디입니까?ASP에서 동기 호출을 비동기 호출로 변환하는 것에 대해 볼 수 있는 멋진 빠른 비디오가 있습니다.Net Core, 아마도 이것을 읽은 후에 갈 방향일 것입니다.아니면 제가 충분히 설명했나요?;)
간단한 콘솔 프로그램에서 작동 중인 위의 설명 표시:
class Program
{
static void Main(string[] args)
{
TestAsyncAwaitMethods();
Console.WriteLine("Press any key to exit...");
Console.ReadLine();
}
public async static void TestAsyncAwaitMethods()
{
await LongRunningMethod();
}
public static async Task<int> LongRunningMethod()
{
Console.WriteLine("Starting Long Running method...");
await Task.Delay(5000);
Console.WriteLine("End Long Running method...");
return 1;
}
}
출력은 다음과 같습니다.
Starting Long Running method...
Press any key to exit...
End Long Running method...
따라서,
- ▁via▁the▁running다▁main▁long▁method를 통해 롱런 방법을 시작합니다.
TestAsyncAwaitMethods되고 ' exit' - 그 동안 내내,
LongRunningMethod백그라운드에서 실행 중입니다.가 이 " " " " 를 합니다.
따라서 스레드가 차단되지 않습니다.
제 생각에 당신은 나쁜 예를 든 것 같습니다.System.Threading.Thread.Sleep
의 점async작업은 다음과 같이 메인 스레드를 잠그지 않고 백그라운드에서 실행되도록 하는 것입니다.DownloadFileAsync
System.Threading.Thread.Sleep그것은 "완료"되는 것이 아닙니다. 그것은 단지 잠을 잡니다. 따라서 당신의 다음 줄은 5초 후에 도달합니다.
기사를 , 저는 이 이기를읽어요세보, 저는그훌설생다각니합고명라륭에 대한 훌륭한 합니다.async그리고.await개념: http://msdn.microsoft.com/en-us/library/vstudio/hh191443.aspx
비동기식 & 간단한 설명 대기
단순 유추
사람들은 아침 기차를 기다릴 수 있습니다.이 작업은 현재 수행 중인 기본 작업이기 때문에 이 작업이 모두 수행되고 있습니다.(연속 프로그래밍 (당신이 평소에 하는 일!)
또 다른 사람은 담배를 피우고 커피를 마시는 동안 아침 기차를 기다릴 수도 있습니다.(비동기식 프로그래밍)
비동기 프로그래밍이란 무엇입니까?
비동기 프로그래밍은 프로그래머가 실행의 주 스레드와 별도의 스레드에서 자신의 코드 중 일부를 실행하도록 선택한 다음 실행이 완료되면 주 스레드에 통지하는 것입니다.
비동기 키워드는 실제로 무엇을 합니까?
다음과 같은 메서드 이름에 비동기 키워드 접두사 붙이기
async void DoSomething(){ . . .
프로그래머는 비동기 작업을 호출할 때 wait 키워드를 사용할 수 있습니다.그게 다야.
이것이 왜 중요합니까?
많은 소프트웨어 시스템에서 메인 스레드는 특히 사용자 인터페이스와 관련된 작업을 위해 예약되어 있습니다.컴퓨터에서 완료하는 데 5초가 걸리는 매우 복잡한 재귀 알고리즘을 실행하고 있지만 메인 스레드(UI 스레드)에서 실행하고 있는 경우사용자가 내 응용프로그램에서 원하는 항목을 클릭하려고 하면 메인 스레드가 대기열에 있고 현재 너무 많은 작업을 처리하고 있기 때문에 프로그램이 중지된 것으로 나타납니다.결과적으로 메인 스레드는 버튼 클릭에서 메소드를 실행하기 위해 마우스 클릭을 처리할 수 없습니다.
비동기 및 대기는 언제 사용합니까?
사용자 인터페이스를 포함하지 않는 모든 작업을 수행할 때는 비동기 키워드를 사용하는 것이 좋습니다.
사용자가 휴대전화로 스케치를 할 수 있는 프로그램을 작성하고 있지만 5초마다 인터넷에서 날씨를 확인할 수 있습니다.
애플리케이션 사용자가 예쁜 그림을 그리기 위해 모바일 터치 스크린과 계속 상호 작용해야 하므로 날씨를 파악하기 위해 5초마다 네트워크에 대한 폴링 콜을 기다려야 합니다.
비동기 및 대기 사용 방법
위의 예에 이어서, 작성 방법에 대한 몇 가지 유사 코드가 있습니다.
//ASYNCHRONOUS
//this is called using the await keyword every 5 seconds from a polling timer or something.
async Task CheckWeather()
{
var weather = await GetWeather();
//do something with the weather now you have it
}
async Task<WeatherResult> GetWeather()
{
var weatherJson = await CallToNetworkAddressToGetWeather();
return deserializeJson<weatherJson>(weatherJson);
}
//SYNCHRONOUS
//This method is called whenever the screen is pressed
void ScreenPressed()
{
DrawSketchOnScreen();
}
추가 정보 - 업데이트
C#에서는 작업에 포함된 메서드만 기다릴 수 있다는 점을 원래 노트에 언급하는 것을 잊었습니다. 예를 들어 다음과 같은 메서드를 기다릴 수 있습니다.
// awaiting this will return a string.
// calling this without await (synchronously) will result in a Task<string> object.
async Task<string> FetchHelloWorld() {..
다음과 같은 작업이 아닌 메서드는 기다릴 수 없습니다.
async string FetchHelloWorld() {..
여기에서 작업 클래스의 소스 코드를 자유롭게 검토하십시오.
다음은 사용자가 쉽게 이해할 수 있도록 빠른 콘솔 프로그램입니다. 그TaskToDoasync를 입니다.으로 실행되도록 하는 은 비기식하작업은에 됩니다.TestAsync 은 테스트 루프 방식으로 진행됩니다.TaskToDo태스크를 실행하고 비동기식으로 실행합니다.실행에서 실행까지 동일한 순서로 완료되지 않기 때문에 결과에서 확인할 수 있습니다. 완료되면 콘솔 UI 스레드에 보고합니다.단순하지만 단순한 예는 더 관련된 예보다 패턴의 핵심을 더 잘 보여준다고 생각합니다.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace TestingAsync
{
class Program
{
static void Main(string[] args)
{
TestLoops();
Console.Read();
}
private static async void TestLoops()
{
for (int i = 0; i < 100; i++)
{
await TestAsync(i);
}
}
private static Task TestAsync(int i)
{
return Task.Run(() => TaskToDo(i));
}
private async static void TaskToDo(int i)
{
await Task.Delay(10);
Console.WriteLine(i);
}
}
}
에 있는 은 여에있모답든변은는을 합니다.Task.Delay()또는 내장된 다른 것.async기능.하지만 여기 그 어떤 것도 사용하지 않는 제 예가 있습니다.async함수:
// Starts counting to a large number and then immediately displays message "I'm counting...".
// Then it waits for task to finish and displays "finished, press any key".
static void asyncTest ()
{
Console.WriteLine("Started asyncTest()");
Task<long> task = asyncTest_count();
Console.WriteLine("Started counting, please wait...");
task.Wait(); // if you comment this line you will see that message "Finished counting" will be displayed before we actually finished counting.
//Console.WriteLine("Finished counting to " + task.Result.ToString()); // using task.Result seems to also call task.Wait().
Console.WriteLine("Finished counting.");
Console.WriteLine("Press any key to exit program.");
Console.ReadLine();
}
static async Task<long> asyncTest_count()
{
long k = 0;
Console.WriteLine("Started asyncTest_count()");
await Task.Run(() =>
{
long countTo = 100000000;
int prevPercentDone = -1;
for (long i = 0; i <= countTo; i++)
{
int percentDone = (int)(100 * (i / (double)countTo));
if (percentDone != prevPercentDone)
{
prevPercentDone = percentDone;
Console.Write(percentDone.ToString() + "% ");
}
k = i;
}
});
Console.WriteLine("");
Console.WriteLine("Finished asyncTest_count()");
return k;
}
이 답변은 ASP 관련 정보를 제공하는 것을 목표로 합니다.그물.
MVC 컨트롤러에서 비동기/대기를 활용하면 아래 기사에서 설명한 것처럼 스레드 풀 활용률을 높이고 훨씬 더 나은 처리량을 달성할 수 있습니다.
http://www.asp.net/mvc/tutorials/mvc-4/using-asynchronous-methods-in-aspnet-mvc-4
시작할 때 많은 수의 동시 요청이 표시되거나 버스트 로드가 있는 웹 응용 프로그램의 경우(동시성이 갑자기 증가하는 경우) 이러한 웹 서비스 호출을 비동기식으로 설정하면 응용 프로그램의 응답성이 향상됩니다.비동기 요청은 동기 요청과 동일한 시간이 소요됩니다.예를 들어 요청이 완료되는 데 2초가 필요한 웹 서비스 호출을 수행하는 경우 요청이 동기식으로 수행되는지 비동기식으로 수행되는지 여부에 관계없이 2초가 걸립니다.그러나 비동기 호출 중에는 스레드가 첫 번째 요청이 완료될 때까지 기다리는 동안 다른 요청에 응답하지 못하도록 차단되지 않습니다.따라서 비동기 요청은 장시간 실행 작업을 호출하는 동시 요청이 많은 경우 요청 대기열 및 스레드 풀 증가를 방지합니다.
비동기 / 대기
사실 비동기 / 대기는 비동기 작업의 콜백을 만들기 위한 구문 설탕인 키워드 쌍입니다.
다음 작업을 예로 들어 보겠습니다.
public static void DoSomeWork()
{
var task = Task.Run(() =>
{
// [RUNS ON WORKER THREAD]
// IS NOT bubbling up due to the different threads
throw new Exception();
Thread.Sleep(2000);
return "Hello";
});
// This is the callback
task.ContinueWith((t) => {
// -> Exception is swallowed silently
Console.WriteLine("Completed");
// [RUNS ON WORKER THREAD]
});
}
위의 코드는 몇 가지 단점이 있습니다.오류는 전달되지 않고 읽기가 어렵습니다.하지만 Async와 Wait는 우리를 도와줍니다.
public async static void DoSomeWork()
{
var result = await Task.Run(() =>
{
// [RUNS ON WORKER THREAD]
// IS bubbling up
throw new Exception();
Thread.Sleep(2000);
return "Hello";
});
// every thing below is a callback
// (including the calling methods)
Console.WriteLine("Completed");
}
대기 호출은 비동기 메서드여야 합니다.이는 다음과 같은 몇 가지 이점은 다음과 같은 이점이 있습니다.
- 작업 결과를 반환합니다.
- 자동으로 콜백 생성
- 오류를 확인하고 오류가 콜 스택에 거품이 일도록 합니다(콜 스택의 비보딩 콜만 해당).
- 결과를 기다립니다.
- 메인 스레드를 해방합니다.
- 메인 스레드에서 콜백을 실행합니다.
- 태스크에 스레드 풀의 작업자 스레드 사용
- 코드를 읽기 쉽게 합니다.
- 그리고 훨씬 더 많은 것들
참고: 비동기 및 대기는 비동기 호출에 사용됩니다.작업 라이브러리를 사용하여 작업을 수행해야 합니다.실행().
다음은 대기와 대기 해결책의 비교입니다.
비 비동기 솔루션은 다음과 같습니다.
public static long DoTask()
{
stopWatch.Reset();
stopWatch.Start();
// [RUNS ON MAIN THREAD]
var task = Task.Run(() => {
Thread.Sleep(2000);
// [RUNS ON WORKER THREAD]
});
// goes directly further
// WITHOUT waiting until the task is finished
// [RUNS ON MAIN THREAD]
stopWatch.Stop();
// 50 milliseconds
return stopWatch.ElapsedMilliseconds;
}
비동기 방법은 다음과 같습니다.
public async static Task<long> DoAwaitTask()
{
stopWatch.Reset();
stopWatch.Start();
// [RUNS ON MAIN THREAD]
await Task.Run(() => {
Thread.Sleep(2000);
// [RUNS ON WORKER THREAD]
});
// Waits until task is finished
// [RUNS ON MAIN THREAD]
stopWatch.Stop();
// 2050 milliseconds
return stopWatch.ElapsedMilliseconds;
}
wait 키워드 없이 비동기 메서드를 호출할 수 있지만 이는 릴리스 모드에서 예외가 모두 사용됨을 의미합니다.
public static Stopwatch stopWatch { get; } = new Stopwatch();
static void Main(string[] args)
{
Console.WriteLine("DoAwaitTask: " + DoAwaitTask().Result + " ms");
// 2050 (2000 more because of the await)
Console.WriteLine("DoTask: " + DoTask() + " ms");
// 50
Console.ReadKey();
}
비동기 및 대기는 병렬 컴퓨팅용이 아닙니다.주 스레드를 차단하지 않는 데 사용됩니다.asp.net 또는 Windows 응용 프로그램과 관련된 경우 네트워크 호출로 인해 메인 스레드를 차단하는 것은 좋지 않습니다.이렇게 하면 앱이 응답하지 않거나 충돌할 수 있습니다.
솔직히 저는 여전히 위키백과의 미래와 약속에 대한 가장 좋은 설명이라고 생각합니다. http://en.wikipedia.org/wiki/Futures_and_promises
기본적인 개념은 태스크를 비동기적으로 실행하는 별도의 스레드 풀이 있다는 것입니다.사용할 때.그러나 개체는 작업을 실행하고 사용자가 요청할 때 결과를 제공한다고 약속합니다.즉, 사용자가 결과를 요청하고 완료하지 않은 경우 차단되지만 그렇지 않으면 스레드 풀에서 실행됩니다.
이를 통해 일부 작업을 비동기식으로 구현할 수 있으며 후속 요청을 일괄 처리하거나 다시 정렬하여 파일 IO 및 네트워크 통신과 같은 작업을 최적화할 수 있습니다.이것이 이미 마이크로소프트의 작업 프레임워크에 있는지는 잘 모르겠지만, 그렇지 않다면 제가 가장 먼저 덧붙일 것 중 하나가 될 것입니다.
실제로 C# 4.0의 수율로 미래 패턴 정렬을 구현할 수 있습니다.정확히 어떻게 작동하는지 알고 싶다면, 괜찮은 일을 할 수 있는 이 링크를 추천해 드릴 수 있습니다. http://code.google.com/p/fracture/source/browse/trunk/Squared/TaskLib/ . 하지만 여러분이 직접 그것을 가지고 놀기 시작한다면, 여러분은 언어 지원이 정말로 필요하다는 것을 알게 될 것입니다. -- 바로 마이크로소프트가 했던 것입니다.
작업, 작업의 사용법을 보여주는 간단한 콘솔 응용 프로그램을 실행하려면 이 fidle https://dotnetfiddle.net/VhZdLU 을 참조하십시오.WaitAll(), 비동기 및 동일한 프로그램의 연산자를 대기합니다.
이 피들은 실행 주기 개념을 지워야 합니다.
여기 샘플 코드가 있습니다.
using System;
using System.Threading.Tasks;
public class Program
{
public static void Main()
{
var a = MyMethodAsync(); //Task started for Execution and immediately goes to Line 19 of the code. Cursor will come back as soon as await operator is met
Console.WriteLine("Cursor Moved to Next Line Without Waiting for MyMethodAsync() completion");
Console.WriteLine("Now Waiting for Task to be Finished");
Task.WaitAll(a); //Now Waiting
Console.WriteLine("Exiting CommandLine");
}
public static async Task MyMethodAsync()
{
Task<int> longRunningTask = LongRunningOperation();
// independent work which doesn't need the result of LongRunningOperationAsync can be done here
Console.WriteLine("Independent Works of now executes in MyMethodAsync()");
//and now we call await on the task
int result = await longRunningTask;
//use the result
Console.WriteLine("Result of LongRunningOperation() is " + result);
}
public static async Task<int> LongRunningOperation() // assume we return an int from this long running operation
{
Console.WriteLine("LongRunningOperation() Started");
await Task.Delay(2000); // 2 second delay
Console.WriteLine("LongRunningOperation() Finished after 2 Seconds");
return 1;
}
}
저는 이것에 대해 2센트를 주고 싶습니다. 만약 제가 설명할 것을 포함하는 다른 답이 있다면, 저는 그것을 대부분 읽었고 찾지 못했지만, 저는 무언가를 놓쳤을 수도 있습니다.
저는 많은 잘못된 개념들과 많은 좋은 설명들을 보았습니다. 비동기식이 병렬 프로그래밍과 어떻게 다른지 설명하고 싶습니다. 저는 이것이 상황을 더 쉽게 이해할 수 있게 해줄 것이라고 믿습니다.
프로세서를 많이 사용하는 장시간의 계산 작업이 필요할 때는 가능하면 병렬 프로그래밍을 사용하여 코어 사용을 최적화해야 합니다.이렇게 하면 일부 스레드가 열리고 동시에 처리됩니다.
일련의 숫자를 가지고 있고 값비싼 긴 계산을 하나 하나 하나 하나로 하고 싶다고 가정해 보겠습니다.평행선은 당신의 친구입니다.
비동기 프로그래밍은 다른 사용 사례에서 사용됩니다.
프로세서에 의존하지 않는 IO(예: 디스크에 쓰기 및 읽기)를 기다릴 때 스레드를 해방하는 데 사용됩니다. IO를 수행할 때 스레드는 아무 것도 하지 않습니다. DB에서 반환되는 값비싼 쿼리의 결과를 기다릴 때와 마찬가지입니다.
비동기 메서드는 결과가 반환될 때까지 기다리는 스레드를 해제합니다.이 스레드는 응용 프로그램의 다른 부분(예: 웹 앱 프로세스의 다른 요청)에서 사용하거나 다른 사용을 위해 OS로 돌아갈 수 있습니다.
결과가 완료되면 동일한 스레드(또는 다른 스레드)가 응용프로그램에 반환되어 처리를 다시 시작합니다.
.net과 같은 멀티 스레드 환경에서는 비동기 프로그래밍이 필수는 아니지만, 웹 앱에서는 다른 스레드가 새로운 요청에 응답하지만, nodejs와 같은 단일 스레드 프레임워크에 있는 경우에는 유일한 스레드를 차단할 수 없거나 다른 요청에 응답할 수 없기 때문에 필수입니다.
요약하자면, 프로세서 집약적인 계산이 길면 병렬 프로그래밍의 이점이 더 크고 IO 또는 DB 쿼리나 일부 API 호출과 같이 프로세서에 의존하지 않는 대기 시간이 길면 비동기 프로그래밍의 이점이 더 큽니다.
예를 들어 Entity Framework에 저장, 나열, 찾기 등의 비동기 api가 있는 이유입니다.
비동기/wait는 wait 또는 waitAll과 동일하지 않습니다. 컨텍스트가 다릅니다.비동기/대기가 스레드를 해제하고 비동기 프로그래밍입니다. wait / wait모든 스레드(해제되지 않음)를 차단하여 병렬 컨텍스트에서 동기화를 강제로 실행합니다. 다른 항목...
이것이 누군가에게 유용하기를 바랍니다.
더 높은 수준에서:
비동기 키워드는 대기를 활성화하고 그것이 전부입니다.비동기 키워드는 메서드를 별도의 스레드에서 실행하지 않습니다.시작 fasync 메서드는 시간이 많이 걸리는 작업에서 대기할 때까지 동기화되어 실행됩니다.
Type의 Task 또는 Task를 반환하는 메서드를 기다릴 수 있습니다.비동기 void 메서드를 기다릴 수 없습니다.
시간이 많이 걸리는 작업에서 주 스레드를 만나는 순간 또는 실제 작업이 시작되면 주 스레드는 현재 메서드의 호출자에게 돌아갑니다.
주 스레드가 아직 실행 중인 작업에서 대기 중임을 확인하면 대기하지 않고 현재 메서드의 호출자에게 돌아갑니다.이러한 방식으로 응용프로그램은 응답 상태를 유지합니다.
처리 작업을 대기합니다. 이제 스레드 풀과 별도의 스레드에서 실행됩니다.
이 대기 작업이 완료되면 아래의 모든 코드가 별도의 스레드에 의해 실행됩니다.
아래는 샘플 코드입니다.실행하고 스레드 ID 확인
using System;
using System.Threading;
using System.Threading.Tasks;
namespace AsyncAwaitDemo
{
class Program
{
public static async void AsynchronousOperation()
{
Console.WriteLine("Inside AsynchronousOperation Before AsyncMethod, Thread Id: " + Thread.CurrentThread.ManagedThreadId);
//Task<int> _task = AsyncMethod();
int count = await AsyncMethod();
Console.WriteLine("Inside AsynchronousOperation After AsyncMethod Before Await, Thread Id: " + Thread.CurrentThread.ManagedThreadId);
//int count = await _task;
Console.WriteLine("Inside AsynchronousOperation After AsyncMethod After Await Before DependentMethod, Thread Id: " + Thread.CurrentThread.ManagedThreadId);
DependentMethod(count);
Console.WriteLine("Inside AsynchronousOperation After AsyncMethod After Await After DependentMethod, Thread Id: " + Thread.CurrentThread.ManagedThreadId);
}
public static async Task<int> AsyncMethod()
{
Console.WriteLine("Inside AsyncMethod, Thread Id: " + Thread.CurrentThread.ManagedThreadId);
int count = 0;
await Task.Run(() =>
{
Console.WriteLine("Executing a long running task which takes 10 seconds to complete, Thread Id: " + Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(20000);
count = 10;
});
Console.WriteLine("Completed AsyncMethod, Thread Id: " + Thread.CurrentThread.ManagedThreadId);
return count;
}
public static void DependentMethod(int count)
{
Console.WriteLine("Inside DependentMethod, Thread Id: " + Thread.CurrentThread.ManagedThreadId + ". Total count is " + count);
}
static void Main(string[] args)
{
Console.WriteLine("Started Main method, Thread Id: " + Thread.CurrentThread.ManagedThreadId);
AsynchronousOperation();
Console.WriteLine("Completed Main method, Thread Id: " + Thread.CurrentThread.ManagedThreadId);
Console.ReadKey();
}
}
}
또한 제가 이해하는 바는, 혼합물에 세 번째 용어가 추가되어야 한다는 것입니다.Task.
Async비동기식 방법이라고 말하기 위해 사용하는 한정자일 뿐입니다.
Task의 귀환입니다.async비동기식으로됩니다.비동기식으로 실행됩니다.
은 너await임무 이 줄에 튀어 .코드 실행이 이 라인에 도달하면 컨트롤이 주변 원래 기능의 호출자에게 다시 튀어 나옵니다.
대에신반당신은을할당다니합환▁▁an▁return▁the다니할▁if의 반환을 할당합니다.async, 함즉, 수수)Task) 변수로, 코드 실행이 이 라인에 도달하면, 그것은 주변 함수에서 그 라인을 지나 계속됩니다.Task비동기적으로 실행됩니다.
public static void Main(string[] args)
{
string result = DownloadContentAsync().Result;
Console.ReadKey();
}
// You use the async keyword to mark a method for asynchronous operations.
// The "async" modifier simply starts synchronously the current thread.
// What it does is enable the method to be split into multiple pieces.
// The boundaries of these pieces are marked with the await keyword.
public static async Task<string> DownloadContentAsync()// By convention, the method name ends with "Async
{
using (HttpClient client = new HttpClient())
{
// When you use the await keyword, the compiler generates the code that checks if the asynchronous operation is finished.
// If it is already finished, the method continues to run synchronously.
// If not completed, the state machine will connect a continuation method that must be executed WHEN the Task is completed.
// Http request example.
// (In this example I can set the milliseconds after "sleep=")
String result = await client.GetStringAsync("http://httpstat.us/200?sleep=1000");
Console.WriteLine(result);
// After completing the result response, the state machine will continue to synchronously execute the other processes.
return result;
}
}
가장 좋은 예는 다음과 같습니다.
이를 사용하는 것이 오랜 기간 논리를 수행하기 위해 배경 스레드를 산란시키는 것과 같습니까?
이 문서는 MDSN: 비동기 프로그래밍과 비동기 및 대기(C#)를 명시적으로 설명합니다.
비동기 및 대기 키워드로 인해 추가 스레드가 생성되지 않습니다.비동기 메서드는 자체 스레드에서 실행되지 않기 때문에 멀티스레딩이 필요하지 않습니다.메소드는 현재 동기화 컨텍스트에서 실행되며 메소드가 활성화된 경우에만 스레드의 시간을 사용합니다.
아래는 대화상자를 열어 엑셀 파일을 읽은 다음 비동기식을 사용하여 엑셀에서 한 줄씩 읽고 그리드에 바인딩하는 코드를 비동기식으로 실행하는 코드입니다.
namespace EmailBillingRates
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
lblProcessing.Text = "";
}
private async void btnReadExcel_Click(object sender, EventArgs e)
{
string filename = OpenFileDialog();
Microsoft.Office.Interop.Excel.Application xlApp = new Microsoft.Office.Interop.Excel.Application();
Microsoft.Office.Interop.Excel.Workbook xlWorkbook = xlApp.Workbooks.Open(filename);
Microsoft.Office.Interop.Excel._Worksheet xlWorksheet = xlWorkbook.Sheets[1];
Microsoft.Office.Interop.Excel.Range xlRange = xlWorksheet.UsedRange;
try
{
Task<int> longRunningTask = BindGrid(xlRange);
int result = await longRunningTask;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message.ToString());
}
finally
{
//cleanup
// GC.Collect();
//GC.WaitForPendingFinalizers();
//rule of thumb for releasing com objects:
// never use two dots, all COM objects must be referenced and released individually
// ex: [somthing].[something].[something] is bad
//release com objects to fully kill excel process from running in the background
Marshal.ReleaseComObject(xlRange);
Marshal.ReleaseComObject(xlWorksheet);
//close and release
xlWorkbook.Close();
Marshal.ReleaseComObject(xlWorkbook);
//quit and release
xlApp.Quit();
Marshal.ReleaseComObject(xlApp);
}
}
private void btnSendEmail_Click(object sender, EventArgs e)
{
}
private string OpenFileDialog()
{
string filename = "";
OpenFileDialog fdlg = new OpenFileDialog();
fdlg.Title = "Excel File Dialog";
fdlg.InitialDirectory = @"c:\";
fdlg.Filter = "All files (*.*)|*.*|All files (*.*)|*.*";
fdlg.FilterIndex = 2;
fdlg.RestoreDirectory = true;
if (fdlg.ShowDialog() == DialogResult.OK)
{
filename = fdlg.FileName;
}
return filename;
}
private async Task<int> BindGrid(Microsoft.Office.Interop.Excel.Range xlRange)
{
lblProcessing.Text = "Processing File.. Please wait";
int rowCount = xlRange.Rows.Count;
int colCount = xlRange.Columns.Count;
// dt.Column = colCount;
dataGridView1.ColumnCount = colCount;
dataGridView1.RowCount = rowCount;
for (int i = 1; i <= rowCount; i++)
{
for (int j = 1; j <= colCount; j++)
{
//write the value to the Grid
if (xlRange.Cells[i, j] != null && xlRange.Cells[i, j].Value2 != null)
{
await Task.Delay(1);
dataGridView1.Rows[i - 1].Cells[j - 1].Value = xlRange.Cells[i, j].Value2.ToString();
}
}
}
lblProcessing.Text = "";
return 0;
}
}
internal class async
{
}
}
질문에 - 할 때 - 사용하기 - 사용하기 - 사용하기async여기 우리가 사용하는 꽤 쉬운 접근법이 있습니다.
- I - use 50ms 딩인장간시 I/O 업작 - 사
async. - CPU 바인딩된 작업을 장시간 실행 - 병렬 실행, 스레드 등을 사용합니다.
설명: 네트워크 요청 전송, 디스크에서 데이터 읽기 등 I/O 작업을 수행할 때 실제 작업은 "외부" 실리콘(네트워크 카드, 디스크 컨트롤러 등)에 의해 수행됩니다.작업이 완료되면 I/O 장치 드라이버가 OS를 "ping"하고 OS는 계속 코드, 콜백 등을 실행합니다.그때까지 CPU는 자유롭게 자체 작업을 수행할 수 있습니다(그리고 보너스로 웹 앱 확장성에 매우 좋은 보너스인 스레드 풀 스레드를 확보할 수도 있습니다).
추신: 50ms 임계값은 MS의 권장 사항입니다. 않으면 그지않추오에 의해 입니다.async(상태 시스템, 실행 컨텍스트 생성 등) 모든 이점을 활용합니다.지금은 MS 원본 기사를 찾을 수 없지만, 여기에도 언급되어 있습니다. https://www.red-gate.com/simple-talk/dotnet/net-framework/the-overhead-of-asyncawait-in-net-4-5/
여기에 제시된 답변은 대기/비동기화에 대한 일반적인 지침으로 유용합니다.또한 대기/비동기 연결 방법에 대한 세부 정보도 포함되어 있습니다.이 디자인 패턴을 사용하기 전에 알아야 할 몇 가지 실제 경험을 공유하고자 합니다.
"wait"라는 용어는 문자 그대로이므로 이를 호출하는 스레드는 계속하기 전에 메서드의 결과를 기다립니다.이것은 재앙입니다.전경 스레드는 보기, 보기 모델, 초기 애니메이션 및 이러한 요소로 부트스트랩된 다른 모든 것을 포함하여 앱을 구성해야 하는 부담을 안고 있습니다.그래서 당신이 전경 스레드를 기다릴 때, 당신은 앱을 중지합니다.사용자는 아무 일도 일어나지 않을 때까지 기다립니다.이는 부정적인 사용자 환경을 제공합니다.
다양한 방법을 사용하여 백그라운드 스레드를 기다릴 수 있습니다.
Device.BeginInvokeOnMainThread(async () => { await AnyAwaitableMethod(); });
// Notice that we do not await the following call,
// as that would tie it to the foreground thread.
try
{
Task.Run(async () => { await AnyAwaitableMethod(); });
}
catch
{}
이러한 의견에 대한 전체 코드는 https://github.com/marcusts/xamarin-forms-annoyances 에 있습니다.WaitAsyncAntipattern.sln이라는 솔루션을 참조하십시오.
GitHub 사이트는 또한 이 주제에 대한 보다 자세한 토론에 대한 링크를 제공합니다.
비동기식은 대기를 사용할 수 있게 해줍니다.기능에 wait를 사용하지 않으면 아무 소용이 없습니다.대기를 사용할 때 대기자의 이름을 근처에 적어야 합니다. 가장 일반적인 이름은 작업 또는 작업입니다.대기는 작업이 완료될 때까지 실행되도록 합니다.완료될 때만 함수의 다음 코드가 실행됩니다.
비동기는 비동기 함수로 만드는 함수와 함께 사용됩니다.wait 키워드는 비동기 함수를 동기적으로 호출하는 데 사용됩니다.wait 키워드는 약속이 해결될 때까지 JS 엔진 실행을 보류합니다.
우리는 즉시 결과를 원할 때만 비동기 & wait를 사용해야 합니다.아마도 함수에서 반환된 결과가 다음 줄에 사용되고 있을 것입니다.
이 블로그를 팔로우하세요, 간단한 단어로 매우 잘 쓰여져 있습니다.
어쩌면 제 통찰력이 관련이 있을 수도 있습니다. async컴파일러에게 함수를 특수하게 처리하도록 지시합니다. 함수는 일시 중단/재개 가능하며, 어떤 방식으로든 상태를 저장합니다. await기능을 일시 중단하지만 규율을 적용하는 방법도 제한적입니다. 기다리고 있는 것을 지정해야 합니다. 이유 없이 일시 중단할 수는 없습니다. 이는 코드를 더 읽기 쉽고 더 효율적으로 만드는 것입니다.이것은 또 다른 질문을 엽니다.그거 좋지await여러 가지, 왜 한 번에 하나씩만?저는 이러한 패턴이 확립되고 프로그래머들이 최소한의 놀라움의 원칙을 따르고 있기 때문이라고 생각합니다.모호성의 가능성이 존재합니다. 당신은 단지 하나의 조건이 충족되기를 원합니까? 아니면 당신은 모든 조건이 충족되기를 원합니까? 아마도 그 중 일부만 충족되기를 원합니까?
언급URL : https://stackoverflow.com/questions/14455293/how-and-when-to-use-async-and-await
'programing' 카테고리의 다른 글
| Angular2에서 이벤트 이미터를 테스트할 방법이 있습니까? (0) | 2023.05.12 |
|---|---|
| 몽구스에서 사용할 때 '트림'의 의미는 무엇입니까? (0) | 2023.05.12 |
| .gitignore 파일은 어디에 속합니까? (0) | 2023.05.12 |
| Powershell을 사용하여 한 Azure Keyvault에서 다른 Keyvault로 모든 비밀을 복사하는 방법 (0) | 2023.05.12 |
| 스위프트 3, 스위프트 4 등에서 어떻게 sync, dispatch_async, dispatch_after 등을 디스패치합니까? (0) | 2023.05.12 |
