작업 순서 지정 및 재입력
작업이 처리되는 것보다 빨리 도착할 수 있고 이전 결과에 따라 달라질 수 있는 시나리오에서는 작업 순서 지정 결정적이 됩니다. 재진입이 필요한 경우 이 문제는 더욱 복잡해집니다.
문제 설명
UI 명령 처리기는 명령을 동기식 또는 비동기식으로 처리할 수 있습니다. 명령이 처리 속도를 초과하는 속도로 도착할 수 있으므로 대기열 및 순차 처리가 필요합니다. 각각의 새로운 작업의 결과는 이전 작업에 따라 달라질 수 있습니다. 단순화를 위해 취소는 제외되지만 재진입은 지원되어야 합니다.
초기 접근
기본 콘솔 앱에서는 AsyncOp 클래스가 작업 순서를 관리합니다. 각 작업은 이전 작업의 연속으로 처리되어 종속성이 충족되도록 합니다. 그러나 재진입이 도입되면 논리가 무너집니다.
동기화 솔루션
이 문제를 해결하기 위해 초기에 예약하지 않고 작업을 수동으로 구성합니다. 대신 "Task.Factory.StartNew"를 사용하여 작업을 동기식으로 실행하여 래퍼 작업이 준비될 때까지 작업이 실행되지 않도록 합니다. 이렇게 하면 순서가 유지됩니다.
코드 구현
class AsyncOp<T> { Task<T> _pending = Task.FromResult(default(T)); public Task<T> CurrentTask => _pending; public Task<T> RunAsync(Func<Task<T>> handler, bool useSynchronizationContext = false) { var pending = _pending; var wrapper = async () => { var prevResult = await pending; Console.WriteLine($"\nprev task result: {prevResult}"); return await handler(); }; var task = new Task<Task<T>>(wrapper); var inner = task.Unwrap(); _pending = inner; task.RunSynchronously(useSynchronizationContext ? TaskScheduler.FromCurrentSynchronizationContext() : TaskScheduler.Current); return inner; } }
업데이트된 출력
Test #1... prev task result: 0 this task arg: 1000 prev task result: 1000 this task arg: 900 prev task result: 900 this task arg: 800 Press any key to continue to test #2... prev task result: 800 this task arg: 100 prev task result: 100 this task arg: 200
확장
이 접근 방식을 통해 추가 개선이 가능합니다. 공유 상태를 보호하기 위해 잠금을 구현하여 스레드 안전성과 같은 것입니다. 또한 작업 중단을 처리하기 위해 취소/다시 시작 논리를 통합할 수 있습니다.
위 내용은 비동기 작업에서 재진입을 통해 작업 순서를 어떻게 유지할 수 있습니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!