내 프로젝트에서 동적 링크 라이브러리의 유형과 인터페이스를 참조합니다. 이 특정 라이브러리를 사용할 때 가장 먼저해야 할 일은 라이브러리 EA.Repository
내에 정의되고 추가 사용을위한 진입 점 역할을 하는의 인스턴스를 만드는 것입니다.
인스턴스화 EA.Repository repository = new EA.Repository()
는 백그라운드에서 복잡한 작업을 수행하며 세 가지 가능한 결과에 직면했습니다.
다음을 사용하여 비동기식 접근 방식을 생각 해낼 수있었습니다 Task
.
public static void Connect()
{
// Do the lengthy instantiation asynchronously
Task<EA.Repository> task = Task.Run(() => { return new EA.Repository(); });
bool isCompletedInTime;
try
{
// Timeout after 5.0 seconds
isCompletedInTime = task.Wait(5000);
}
catch (Exception)
{
// If the instantiation fails (in time), throw a custom exception
throw new ConnectionException();
}
if (isCompletedInTime)
{
// If the instantiation finishes in time, store the object for later
EapManager.Repository = task.Result;
}
else
{
// If the instantiation did not finish in time, throw a custom exception
throw new TimeoutException();
}
}
(아마도 여기에서 이미 많은 문제를 발견 할 수 있습니다. 잠시만 기다려주세요 ... 권장 사항을 주시면 감사하겠습니다!)
이 방법은 지금까지 작동합니다. "예외"및 "시간 초과"시나리오를 모두 시뮬레이션 할 수 있으며 원하는 동작을 얻을 수 있습니다.
그러나 다른 경우를 확인했습니다. 인스턴스화 작업이 시간 초과가 만료되고 예외가 발생하는 데 충분히 오래 걸린다고 가정 해 보겠습니다. 이 경우 AggregateException
작업이 관찰되지 않았다는 말이 나오기도 합니다.
나는 이것에 대한 실행 가능한 해결책을 찾기 위해 고군분투하고 있습니다. 차단 인스턴스화로 인해 CancellationToken
접근 방식 을 사용하지 못하기 때문에 제한 시간이 만료되면 작업을 취소 할 수 없습니다 .
내가 생각 해낼 수있는 유일한 방법은 내 커스텀을 던지기 직전에 비동기 적으로 작업을 관찰 (즉, 다른 작업을 시작)하는 것입니다 TimeoutException
.
Task observerTask = Task.Run(() => {
try { task.Wait(); }
catch (Exception) { }
});
throw new TimeoutException();
물론 인스턴스화가 정말 영원히 차단된다면, 이미 첫 번째 작업이 끝나지 않았을 것입니다. 관찰자 작업으로 이제 두 개도 있습니다!
이 모든 접근 방식에 대해 매우 안전하지 않으므로 어떤 조언도 환영합니다!
미리 감사드립니다!
다음은 관찰되지 않는 동안 실패 할 수있는 작업을 명시 적으로 관찰하는 데 사용할 수있는 확장 방법입니다.
public static Task<T> AsObserved<T>(this Task<T> task)
{
task.ContinueWith(t => t.Exception);
return task;
}
사용 예 :
var task = Task.Run(() => new EA.Repository()).AsObserved();
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다