2009-05-21 4 views
2

.NET (C#)의 이벤트에 대한 질문이 있습니다. 백그라운드 작업을 실행하는 여러 상황에 대한 코드를 작성해야하고 주 스레드 또는 컨트롤러 클래스에 작업 완료 또는 파일 복사 완료와 같은 문제가 발생했음을 알리고 싶습니다. 백그라운드 스레드가 주 스레드의 델리게이트가 이벤트를 처리 할 때까지 기다릴 수 있습니다.이벤트 리스너가 실행되기를 기다리지 않고 어떻게 이벤트를 시작할 수 있습니까?

메시지 전달과 같은 작업을 수행하고 싶습니다. 메시지를 보내지 만 누가 그 메시지를 처리하는지 신경 쓰지 않습니다. 예를 들어

:

클래스가 순서대로 몇 개의 프로세스 하나씩 처리에 기록된다. 각 프로세스는 백그라운드 스레드에서 실행해야합니다. 작업이 완료되면 이벤트가 시작되고 컨트롤러에 완료되었음을 알립니다 (OnCompleted() 메서드 사용).

문제는 컨트롤러의 이벤트 처리기를 사용하여 후속 프로세스를 시작하면 이전 프로세스의 OnComplete 메서드는 모든 프로세스가 완료 될 때까지 호출 스택에 남아 있습니다 (실행을 완료하지 않음).

그런 상황에서 백그라운드 작업이 스택에서 이벤트 발생 메서드를 유지하지 않고 작업이 완료되었다는 것을 컨트롤러 클래스에 어떻게 알릴 수 있습니까?

예제 2 : 백업 프로그램.

각 파일을 대상에 복사하기위한 백그라운드 스레드가 실행됩니다. 배경이 이면 UI에 복사 된 마지막 파일 인을 알릴 필요가 있지만 UI가 업데이트 될 때까지 기다릴 필요가 없습니다. 대신에, "BTW, 여기에 정보가 있습니다. 이제 다시 일하러 가자." 이벤트 수신기는 이벤트 발생 자의 처리를 차단해서는 안됩니다.

답변

2

:

void OnUpdated(EventArgs e) { 
    EventHandler h = this.Updated; 
    if (h != null) h(e); 
} 

void DoStuff() { 
    BigMethod(); 
    ThreadPool.QueueUserWorkItem(OnUpdated, EventArgs.Empty); 
    BigMethod2(); 
} 

비동기 올리면

는, 다수의 청취자가 처리 될 것이다 당신의 동시에 이벤트. 최소한 스레드로부터 안전한 EventArg 클래스가 필요합니다.클래스와도 상호 작용할 것으로 기대된다면 매우 신중하게 문서화하거나 스레드로부터 안전하게 처리해야합니다.

백그라운드 스레드에서 이벤트를 발생 시키면 클래스 메서드에 대해 동일한주의 사항이 적용되지만 EventArgs 클래스 자체에 대해 걱정할 필요가 없습니다.

1

첫 번째 이벤트가 아무 것도하지 않고 스레드를 시작한 다음 다른 이벤트 리스너가 무엇인지는 중요하지 않습니다.

+0

가 어떻게한다는 점에서 C#을 할 것 코딩 asyn의 다른 기술을 말한다? –

+0

음, 다른 스레드를 시작하는 방법을 알고있는 것 같습니다. 첫 번째 이벤트 리스너가이 작업을 수행하도록하십시오. (이벤트를 사용하여 객체를 생성하자마자 –

3

이벤트 호출 목록에서 대리자를 비동기 적으로 호출하는 것처럼 들립니다. 내가 제안

당신은 .NET Asynchronous Events To Send Process Status To User Interface을 읽어 :

.NET 프레임 워크는 비동기 적으로 우리에게 우리의 클래스에서 이벤트를 높이는 개념 (및 기타 항목)를 제공합니다. 즉, 해당 이벤트에 가입자 (일반적으로 사용자 인터페이스)가 없으므로 이벤트를 발생시켜 이벤트를 발생시킨 메서드에서 처리를 보류 할 수 있습니다. 이점은 은 메서드의 성능에 부정적인 영향을 미치지 않습니다.

당신은 (언급 한 바와 같이) 이벤트를 제기 할 때 비동기 호출을 수행하거나 백그라운드 스레드에서 이벤트 자체를 올릴 수
+0

BeginInvoke/EndInvoke 패턴에 대해 읽은 핸들러를 할당합니다.하지만 리스너 측이 아닌 리스너 측에서 사용하려고 생각했습니다. 미해결 BeginInvoke 전화가 많이 발생하는 경우 문제가있을 수 있습니까? –

0

사례 2의 백업 프로그램입니다. 코드 샘플은 파일 사본을 비동기 적으로 실행하고 복사가 완료되면 콜백 메소드를 호출합니다.

: 업데이트하는 UI를 기다릴 싶지 않는 경우 콜백에서, 당신은 당신이로 호출 할 수 있습니다 비동기

당신은 비동기 대표

public class AsyncFileCopier 
    { 
     public delegate void FileCopyDelegate(string sourceFile, string destFile); 

     public static void AsynFileCopy(string sourceFile, string destFile) 
     { 
      FileCopyDelegate del = new FileCopyDelegate(FileCopy); 
      IAsyncResult result = del.BeginInvoke(sourceFile, destFile, CallBackAfterFileCopied, null); 
     } 

     public static void FileCopy(string sourceFile, string destFile) 
     { 
      // Code to copy the file 
     } 

     public static void CallBackAfterFileCopied(IAsyncResult result) 
     { 
      // Notify UI by calling an async del (probably using fire & forget approach or another callback if desired) 
     } 
    } 

를 사용할 수있는 UI 업데이트 코드를 호출해야합니다

AsyncFileCopier.AsynFileCopy("abc.txt", "xyz.txt"); 

link 당신에게

관련 문제