정적 클래스에서 사용자 지정 이벤트를 발생시키는 방법
해당 클래스의 정적 메서드 내에서 트라이 캐치 블록의 일부로 이벤트를 발생시키고 싶은 정적 클래스가 있습니다.
예를 들어 이 방법으로 캐치에서 커스텀 이벤트를 발생시키고 싶습니다.
public static void saveMyMessage(String message)
{
try
{
//Do Database stuff
}
catch (Exception e)
{
//Raise custom event here
}
}
감사해요.
중요: 인스턴스에서 정적 이벤트를 구독할 때는 매우 주의해야 합니다.정적에서 정적으로 전환하는 것은 괜찮지만 정적 이벤트에서 인스턴스 핸들러로 구독하는 것은 해당 인스턴스를 영원히 활성화할 수 있는 좋은(읽기: 매우 위험함) 방법입니다.GC는 링크를 볼 것이며, 사용자가 구독을 취소하지 않는 한(또는 약한 참조와 같은 것을 사용하지 않는 한) 인스턴스를 수집하지 않습니다.
정적 이벤트를 만드는 패턴은 인스턴스 이벤트와 동일합니다. 단지static
:
public static event EventHandler SomeEvent;
여기서 유용한 트릭은 삶을 더 쉽게 하기 위해(리널 검사) 사소한 핸들러를 추가하는 것입니다.
public static event EventHandler SomeEvent = delegate {};
그런 다음 null-check 없이 간단히 호출할 수 있습니다.
SomeEvent(null, EventArgs.Empty);
대리자 인스턴스는 불변이고 참조 해제는 스레드 안전하므로 여기에는 레이스 조건이 없으며 잠글 필요도 없습니다.참조 해제가 호출되면 who-very가 구독됩니다.
(자신의 이벤트 인수 등에 맞게 조정).이 트릭은 인스턴스 이벤트에도 동일하게 적용됩니다.
이벤트도 정적이어야 합니다.
public class ErrorEventArgs : EventArgs
{
private Exception error;
private string message;
public ErrorEventArgs(Exception ex, string msg)
{
error = ex;
message = msg;
}
public Exception Error
{
get { return error; }
}
public string Message
{
get { return message; }
}
}
public static class Service
{
public static EventHandler<ErrorEventArgs> OnError;
public static void SaveMyMessage(String message)
{
EventHandler<ErrorEventArgs> errorEvent = OnError;
if (errorEvent != null)
{
errorEvent(null, new ErrorEventArgs(null, message));
}
}
}
및 사용:
public class Test
{
public void OnError(object sender, ErrorEventArgs args)
{
Console.WriteLine(args.Message);
}
}
Test t = new Test();
Service.OnError += t.OnError;
Service.SaveMyMessage("Test message");
몇몇 사람들이 코드 예제를 제안했습니다. 단지 다음과 같은 코드를 사용하여 이벤트를 발생시키지 마십시오.
if(null != ExampleEvent)
{
ExampleEvent(/* put parameters here, for events: sender, eventArgs */);
}
이벤트를 null로 확인할 때와 실제로 이벤트를 실행할 때 사이의 경합 조건이 포함되어 있습니다.대신 단순 변동을 사용합니다.
MyEvent exampleEventCopy = ExampleEvent;
if(null != exampleEventCopy)
{
exampleEventCopy(/* put parameters here, for events: sender, eventArgs */);
}
이렇게 하면 이벤트 가입자가 exampleEventCopy에 복사됩니다. 그러면 레이스 조건에 대해 걱정할 필요 없이 이를 공용 이벤트의 로컬 전용 버전으로 사용할 수 있습니다(기본적으로,사용자가 공개 이벤트를 null로 확인한 직후 다른 스레드가 사용자를 선점하여 이벤트에서 모든 구독자를 제거함으로써 이벤트의 후속 실행에 예외가 발생할 수 있습니다. 로컬 전용 복사본을 사용하면 다른 스레드가 구독자를 제거할 가능성을 피할 수 있습니다.로컬 변수에 액세스할 수 없기 때문입니다.)
참고: VS2008, C#
일반적으로 정적 클래스 내에서 하는 것처럼 이벤트를 선언하지만 이벤트를 정적으로 표시해야 합니다.
public static event EventHandler Work;
그럼 그냥 평소처럼 구독하세요.
"위의 예제에서 볼 수 있듯이, 딜러는 불변입니다."라고 덧붙이기만 하면 다음 행에서 딜러의 복사본을 얻을 수 있습니다.
EventHandler<ErrorEventArgs> errorEvent = OnError;
이 작업을 수행한 방법은 다음과 같습니다.
1 - 대리자를 정의합니다(사용자 정의된 인수를 사용할 수 있습니다).
public delegate void CustomeEventHandler(string str);
2- 이전에 정의한 대리자를 기준으로 이벤트를 정의합니다.
public static event CustomeEventHandler ReadLine;
3- 이벤트 핸들러를 만듭니다.
static void OnLineRead(string currentLine)
{
if (ReadLine != null)
ReadLine(currentLine);
}
4 - 이벤트 핸들러를 사용하여 이벤트를 제기합니다(이벤트가 제기되기를 원하는 곳이면 어디든 호출하십시오).
언급URL : https://stackoverflow.com/questions/289002/how-to-raise-custom-event-from-a-static-class
'programing' 카테고리의 다른 글
유형 스크립트 결합 유형에서 다른 속성 액세스 (0) | 2023.07.05 |
---|---|
특정 커밋이 포함된 병합 커밋 찾기 (0) | 2023.07.05 |
오라클에서 숫자 데이터가 포함되지 않은 행 찾기 (0) | 2023.07.05 |
리비전 번호에 대한 Git 등가물은 무엇입니까? (0) | 2023.07.05 |
셀 내의 16진수 색상 값을 사용하여 셀을 강조 표시하는 방법은 무엇입니까? (0) | 2023.07.05 |