제한 사항 이해: C#의 await
및 lock
C#의 await
키워드는 비동기 프로그래밍에 매우 중요하며 비차단 작업을 가능하게 합니다. 그러나 await
문 안에 lock
을 사용하는 것은 엄격히 금지됩니다. 이 제한은 일반적인 오류 원인인 교착 상태를 방지하기 위한 주요 설계 선택입니다.
Microsoft 설명서에서는 await
내의 lock
표현식이 위험을 초래한다고 설명합니다. 코드 실행은 await
이 제어권을 얻은 후 일시 중지되고 나중에 잠재적으로 다른 스레드에서 다시 시작될 수 있습니다. 이러한 타이밍 차이로 인해 다른 스레드가 잠금을 획득하여 잠금 순서가 바뀌고 교착 상태가 발생하는 상황이 발생할 수 있습니다.
가설적인 예를 살펴보겠습니다.
class Async { public static async Task<IDisposable> Lock(object obj) { while (!Monitor.TryEnter(obj)) await Task.Yield(); return new ExitDisposable(obj); } private class ExitDisposable : IDisposable { private readonly object obj; public ExitDisposable(object obj) { this.obj = obj; } public void Dispose() { Monitor.Exit(this.obj); } } }
이 코드는 비동기 잠금을 모방하려고 시도하지만 컴파일러에서 알 수 있듯이 ExitDisposable.Dispose()
내에서 무기한 차단이 발생하여 교착 상태가 발생할 가능성이 있습니다. 이는 Monitor.Exit
이 잠금을 획득한 스레드와 다른 스레드에서 실행되어 잠재적으로 잠금 순서를 위반할 수 있기 때문에 발생합니다.
본질적으로 await
내의 lock
금지는 멀티스레드 애플리케이션의 교착 상태를 방지하기 위한 사전 조치입니다. lock
문과 비동기 작업을 결합하는 것을 피하고 리더-라이터 잠금 또는 System.Threading
의 동기화 프리미티브와 같은 대체 동기화 방법을 고려하는 것이 가장 좋습니다.
위 내용은 C#의 'lock' 문 내에서 'await'가 금지되는 이유는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!