문제

개념적으로 다음을 수행하고 싶지만 C#에서 올바르게 코딩하는 방법을 이해하는 데 어려움을 겪었습니다.


SomeMethod { // Member of AClass{}
    DoSomething;
    Start WorkerMethod() from BClass in another thread;
    DoSomethingElse;
}

그런 다음 WorkerMethod()가 완료되면 다음을 실행합니다.


void SomeOtherMethod()  // Also member of AClass{}
{ ... }

누구든지 그 예를 들어 주시겠습니까?

도움이 되었습니까?

해결책

그만큼 배경작업자 정확한 목적을 위해 클래스가 .NET 2.0에 추가되었습니다.

간단히 말해서 다음을 수행합니다.

BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += delegate { myBClass.DoHardWork(); }
worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(SomeOtherMethod);
worker.RunWorkerAsync();

원하는 경우 취소 및 진행 상황 보고와 같은 멋진 기능을 추가할 수도 있습니다. :)

다른 팁

.Net 2에서는 BackgroundWorker가 도입되어 비동기 작업 실행이 매우 쉬워졌습니다.

BackgroundWorker bw = new BackgroundWorker { WorkerReportsProgress = true };

bw.DoWork += (sender, e) => 
   {
       //what happens here must not touch the form
       //as it's in a different thread
   };

bw.ProgressChanged += ( sender, e ) =>
   {
       //update progress bars here
   };

bw.RunWorkerCompleted += (sender, e) => 
   {
       //now you're back in the UI thread you can update the form
       //remember to dispose of bw now
   };

worker.RunWorkerAsync();

.Net 1에서는 스레드를 사용해야 합니다.

AsyncCallBacks를 사용해야 합니다.AsyncCallBacks를 사용하여 메서드에 대리자를 지정한 다음 대상 메서드 실행이 완료되면 호출되는 콜백 메서드를 지정할 수 있습니다.

다음은 작은 예입니다. 직접 실행하여 확인해 보세요.

클래스 프로그램 {

    public delegate void AsyncMethodCaller();


    public static void WorkerMethod()
    {
        Console.WriteLine("I am the first method that is called.");
        Thread.Sleep(5000);
        Console.WriteLine("Exiting from WorkerMethod.");
    }

    public static void SomeOtherMethod(IAsyncResult result)
    {
        Console.WriteLine("I am called after the Worker Method completes.");
    }



    static void Main(string[] args)
    {
        AsyncMethodCaller asyncCaller = new AsyncMethodCaller(WorkerMethod);
        AsyncCallback callBack = new AsyncCallback(SomeOtherMethod);
        IAsyncResult result = asyncCaller.BeginInvoke(callBack, null);
        Console.WriteLine("Worker method has been called.");
        Console.WriteLine("Waiting for all invocations to complete.");
        Console.Read();

    }
}

여기에는 여러 가지 가능성이 있지만 저는 다음을 사용하여 비동기식으로 호출되는 대리자를 사용하겠습니다. BeginInvoke 방법.

경고 :항상 전화하는 것을 잊지 마세요 EndInvokeIAsyncResult 에 설명된 대로 최종적인 메모리 누수를 방지하려면 이 기사.

BackgroundWorker를 확인하세요.

비동기 대리자를 사용합니다.

// Method that does the real work
public int SomeMethod(int someInput)
{
Thread.Sleep(20);
Console.WriteLine(”Processed input : {0}”,someInput);
return someInput+1;
} 


// Method that will be called after work is complete
public void EndSomeOtherMethod(IAsyncResult result)
{
SomeMethodDelegate myDelegate = result.AsyncState as SomeMethodDelegate;
// obtain the result
int resultVal = myDelegate.EndInvoke(result);
Console.WriteLine(”Returned output : {0}”,resultVal);
}

// Define a delegate
delegate int SomeMethodDelegate(int someInput);
SomeMethodDelegate someMethodDelegate = SomeMethod;

// Call the method that does the real work
// Give the method name that must be called once the work is completed.
someMethodDelegate.BeginInvoke(10, // Input parameter to SomeMethod()
EndSomeOtherMethod, // Callback Method
someMethodDelegate); // AsyncState

좋아, 당신이 이 문제를 어떻게 해결하고 싶은지 잘 모르겠습니다.귀하의 예에서 WorkerMethod는 실행할 자체 스레드를 생성하지 않지만 다른 스레드에서 해당 메서드를 호출하려는 것처럼 보입니다.

이 경우 WorkerMethod를 호출한 다음 SomeOtherMethod를 호출하고 해당 메서드를 다른 스레드에 대기시키는 짧은 작업자 메서드를 만듭니다.그런 다음 WorkerMethod가 완료되면 SomeOtherMethod가 호출됩니다.예를 들어:

public class AClass
{
    public void SomeMethod()
    {
        DoSomething();

        ThreadPool.QueueUserWorkItem(delegate(object state)
        {
            BClass.WorkerMethod();
            SomeOtherMethod();
        });

        DoSomethingElse();
    }

    private void SomeOtherMethod()
    {
        // handle the fact that WorkerMethod has completed. 
        // Note that this is called on the Worker Thread, not
        // the main thread.
    }
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top