별도의 스레드에서 오류를 전파하는 가장 좋은 방법은 무엇입니까 (예 : 시작 블록, Proc :: Async 또는 이들을 포함하는 하위). try / CATCH 블록에서 새 스레드를 분리하는 코드를 래핑하는 것만으로는 작동하지 않으며 await를 사용하면 하위 루틴의 반환 값에 따라 작동합니다 (즉, 하위 반환 자체는 await 접근 방식에서는 작동하지 않음).
별도의 스레드에서 오류를 전파하는 가장 좋은 방법은 무엇입니까 (예 : 시작 블록, Proc :: Async 또는 이들을 포함하는 하위). try / CATCH 블록에서 새 스레드를 분리하는 코드를 래핑하는 것만으로는 작동하지 않으며 await를 사용하면 하위 루틴의 반환 값에 따라 작동합니다 (즉, 하위 반환 자체는 await 접근 방식에서는 작동하지 않음).
답변:
이론적으로 그 코드 는 죽어야한다 .
6.d 버전의 언어에서 싱크 컨텍스트에 사용 된 start 문 접두사는 자동으로 예외 처리기를 연결합니다. 주어진 코드에서 예외가 발생하면 시작 명령문 접두어가 포함되지 않고 발생 된 것처럼 인쇄되고 프로그램이 종료됩니다.
use v6.c;
start { die }; sleep ⅓; say "hello"; # OUTPUT: «hello»
use v6.d;
start { die }; sleep ⅓; say "hello";
# OUTPUT:
# Unhandled exception in code scheduled on thread 4
# Died
# in block at -e line 1
이 경우 약속을 싱크하지 않기 때문에 이상한 상황입니다 (반환하고 있습니다). 그러나 결국 빈 공간에서 실행하기 때문에 싱크합니다.
동일한 문서가 솔루션을 제공합니다. 컨텍스트를 싱크하지 마십시오.
# Don't sink it:
my $ = start { die }; sleep ⅓; say "hello"; # OUTPUT: «hello»
# Catch yourself:
start { die; CATCH { default { say "caught" } } };
sleep ⅓;
say "hello";
당신의 프로그램은 죽지 않기 때문에 두 번째 상황에 있다고 말할 것입니다. 어떤 이유로 든 침몰하지 않습니다. 그러나 어떤 상황이든 솔루션은 동일합니다. 동일한 코드 블록 내에서 예외를 잡아야합니다.
해결책 : await
주변 코드가 죽을 수 있도록 약속 (싱크되지 않음) 또는 변수에 할당하십시오. 그러나 OP에 응답하면 아니요. 다른 블록에서 예외를 잡을 수없는 것과 같은 방식으로 다른 스레드에서 예외를 잡을 수 없습니다.
채널을 사용하여 이동 루틴에서 오류를 전달하기 위해 Go에 사용 된 규칙에 따라 Raku에서도 동일한 접근 방식을 찾았습니다. 채널을 사용하여 메인 스레드에서 처리 할 비동기 코드에서 오류를 보낼 수 있습니다.
예:
my $errors = Channel.new;
my $err-supply = $errors.Supply;
$err-supply.tap(-> $e {say "handle error: $e"});
start {
die "something went horribly wrong";
CATCH {
default {
$errors.send($_);
}
}
}
sleep 1;
foo
및bar
여기에 제거 할 수 있습니까?