예외의 소멸자를 정리 코드를 넣을 장소로 사용할 수 있습니까?C++ 예외의 소멸자 코드 정리
이렇게하면 클라이언트가 RAII와 반대되는 최종 단계를 제어 할 수 있습니다. 좋은 디자인입니까 아니면 나쁜 디자인입니까? OOP 및 C++의 컨텍스트에서 올바른 솔루션입니까?
현재 비동기 적으로 여러 작업을 시작하는 비동기 프로 시저에서 작업 중입니다. 다음과 같이 패턴은 같습니다
struct IAsyncResult
{
...
virtual void EndCall() const;
}
typedef std::shared_ptr<IAsyncResult> IAsyncResultPtr;
struct IAsyncTask
{
virtual IAsyncResultPtr BeginTask() = 0;
virtual void EndTask(IAsyncResultPtr async) const = 0;
}
class CompositeTask : public IAsyncTask
{
…
}
불행하게도 나는 각 하위의 BeginTask 방법이 실패하지 않을 것이라는 보장 드릴 수 없습니다. 따라서 N-1 부 작업이 성공적으로 시작되고 N 번째 작업이 실패 할 수 있습니다.
일반적으로 클라이언트 코드가 완료되기 전에 백그라운드 작업이 실행되고 있지 않은지 확인하는 것이 중요합니다. 그러나 때로는 클라이언트가 일부 작업이 실패하더라도 걱정하지 않습니다.
그래서 내 현재 솔루션은 한 작업을 시작하지 못한 경우를 대비해 CompositeTask의 BeginAsync 메서드에서 발생하는 사용자 지정 예외를 포함합니다. 이것은 클라이언트가 청소 단계 제어 할 수 있습니다 :
class composite_async_exception : public std::exception
{
std::vector<IAsyncResultPtr> successfully_started_tasks;
mutable bool manage_cleanup;
public:
composite_async_exception(std::vector<IAsyncResultPtr> const& _successfully_started_tasks)
: successfully_started_tasks(_successfully_started_tasks)
, manage_cleanup(true)
{
}
virtual ~composite_async_exception() throw()
{
if(!manage_cleanup)
return;
for(auto task = successfully_started_tasks.begin(); task != successfully_started_tasks.end(); ++task)
{
task->CancelTask();
}
}
void Giveup() const throw()
{
manage_cleanup = false;
}
};
을 그리고 클라이언트는 그림과 같이 코드를 사용
try
{
compositeTask.BeginAsync();
}
catch(composite_async_exception const& ex)
{
//prevent the exception to cancel tasks
ex.Giveup();
// some handling
}
이러한 상황을 처리하는 몇 가지 모범 사례가 있습니까를?
하나의 가능성은 각 하위 작업의 진행을 줄 수있는에 ITaskProgress 인터페이스를 가지고있다 클래스 ITaskProgress { 공개 : 무효의 UpdateProgress (<어떤 자식 작업을 식별>, 부울 aSuccess, 부울 & aContinue) = 0; }; 클라이언트는이 인터페이스를 구현하고 복합 작업으로 인스턴스 및 등록 할 수 있습니다. 이제 클라이언트는 알림을 받고 클라이언트는 계속할지 여부를 결정할 수 있습니다. – PermanentGuest
제 질문이 잘못 공식화되었음을 압니다. 그래서 나는 그것을 바꿨다. –