사용자 지정 공급자 설정 예제
이 항목에서는 사용자 지정 비동기 공급자를 설정하는 방법의 예를 제공합니다. 사용자 지정 비동기 공급자를 작성할 때는 XAsyncBegin을 호출하여 비동기 메서드를 시작합니다. 이 기능에는 예를 들어, 상태 변경 처리, 콜백을 큐에 추가, 완료 트리거 등을 구현하는 콜백 매개 변수가 있습니다.
struct Context
{
uint64_t result;
};
Context* context = new Context{ 0 };
// Assume that the async block is already filled out with the completion callback and task queue.
HRESULT hr = XAsyncBegin(async, context, ProviderFuncIdentity, __FUNCTION__,
[](XAsyncOp op, const XAsyncProviderData* providerData)
{
Context* context =
reinterpret_cast<Context*>(providerData->context);
switch (op)
{
case XAsyncOp::Begin:
return XAsyncSchedule(providerData->async, 0);
case XAsyncOp::Cleanup:
delete context;
break;
case XAsyncOp::GetResult:
memcpy(providerData->buffer, &context->result, sizeof(uint64_t));
break;
case XAsyncOp::DoWork:
context->result = 12345678;
XAsyncComplete(providerData->async, S_OK, sizeof(uint64_t));
break;
case XAsyncOp::Cancel:
// This call can't be canceled.
break;
}
return S_OK;
});
여기에서 압축을 풀어야 할 것이 많이 있지만 기본 개념은 직접 전달입니다. XAsyncBegin
을(를) 호출하고 이를 공급자 콜백에 전달하여 다양한 상태 변경을 처리합니다. 사용할 작업 큐뿐만 아니라 완료 콜백의 선택적 구현이 비동기 블록에 포함된다는 것을 유념하십시오. 그런 다음 콜백은 다음 표와 같이 비동기 작업의 런타임에 대해 5가지 다른 사례를 처리해야 합니다.
공급자 사례 | 책임 |
---|---|
Begin |
XAsyncBegin 에 대한 호출로 즉시 호출되었습니다. 이 사례는 작업 큐 쪽으로 비동기 작업 콜백의 예약을 담당합니다. 이는 XAsyncSchedule을 호출하여 처리됩니다. 이 작업은 이 콜백을 큐에 추가하여 작업 큐의 작업 포트를 통해 DoWork 사례로 다시 실행합니다. |
Cleanup |
비동기 작업이 완료되고 추적을 위해 생성된 내부 데이터를 삭제할 수 있을 때 호출됩니다. 이전 예제 코드의 경우 이 사례는 결과 데이터를 계속 추적하기 위해 할당된 Context 구조체를 정리합니다. |
GetResult |
사용자가 XAsyncGetResult를 호출할 때 호출됩니다. 그런 다음 사례는 전달받는 출력 버퍼에 쓰기를 수행해야 합니다. 따라서 원래의 비동기 결과가 어딘가에 저장되어야 합니다. 이전 예제 코드는 결과를 Context 구조에 저장합니다.비동기 작업에서 데이터를 반환하는 비동기 Microsoft GDK(게임 개발 키트) API 함수는 내부적으로 XAsyncGetResult 을(를) 호출하고 해당 데이터를 호출자에게 적합한 형식으로 변환합니다. 결과를 다루는 경우 이렇게 하는 것이 좋습니다. |
DoWork |
작업 포트를 디스패치한 작업 큐를 통해 호출됩니다. 즉, 이 콜백의 스택 프레임은 작업 큐가 설정된 방식을 기준으로 의도된 스레드에서 실행합니다. 모든 작업은 여기에서 수행해야 합니다. XAsyncRun의 내부 비동기 공급자 구현에서는 여기에서 전달된 작업 콜백이 실행됩니다. 사용자 지정 공급자의 경우 작업은 콜백에서 바로 수행되거나 기능을 캡슐화하는 일부 사용자 지정 메서드로 수행될 수 있습니다. 작업이 완료되면 XAsyncComplete을 호출해야 합니다. 이 함수는 2가지 작업을 수행합니다. 먼저, 이는 데이터 크기를 제공함으로써 출력 데이터가 필요한지 여부를 지정합니다. 0 이상 값이 제공되는 경우 쓰기를 수행할 GetResult 사례에 대해 내부 버퍼가 할당됩니다. 둘째, 이는 작업 큐의 완료 포트에서 실행될 수 있도록 완료 콜백에 대한 호출을 큐에 추가합니다.
XAsyncComplete 에 전달된 완료 상태 코드는 XAsyncGetStatus에 대한 호출에서 반환된 코드가 됩니다. |
Cancel |
XAsyncCancel에 대한 외부 호출을 통해 트리거됩니다. 이 사례가 구현되지 않으면 결과적으로 아무 일도 발생하지 않습니다. 취소할 수 있도록 공급자는 실행 중인 모든 작업이 정지할 때까지 신호를 전달할 수 있어야 합니다. 그런 다음 DoWork 사례는 E_ABORT 상태의 XAsyncComplete 을(를) 호출해야 합니다. |