development

비동기 메서드가 값을 반환하도록하는 방법은 무엇입니까?

big-blog 2020. 11. 6. 21:04
반응형

비동기 메서드가 값을 반환하도록하는 방법은 무엇입니까?


비동기 메서드를 만드는 방법을 알고 있지만 많은 작업을 수행 한 다음 부울 값을 반환하는 메서드가 있다고 말합니까?

콜백에서 부울 값을 어떻게 반환합니까?

설명 :

public bool Foo(){
    Thread.Sleep(100000); // Do work
    return true;
}

나는 이것을 비동기로 만들 수 있기를 원합니다.


이를 수행하는 몇 가지 방법이 있습니다. 가장 간단한 방법은 비동기 메서드가 후속 작업을 수행하도록하는 것입니다. 또 다른 인기있는 접근 방식은 콜백을 전달하는 것입니다.

void RunFooAsync(..., Action<bool> callback) {
     // do some stuff
     bool result = ...

     if(callback != null) callback(result);
}

또 다른 접근 방식은 비동기 작업이 완료 될 때 이벤트 (event-args 데이터의 결과 포함)를 발생시키는 것입니다.

또한 TPL을 사용하는 경우 다음을 사용할 수 있습니다 ContinueWith.

Task<bool> outerTask = ...;
outerTask.ContinueWith(task =>
{
    bool result = task.Result;
    // do something with that
});

에서 C # 5.0 , 당신은 방법을 지정할 수 있습니다

public async Task<bool> doAsyncOperation()
{
    // do work
    return true;
}

bool result = await doAsyncOperation();

아마 그것을 할 수있는 간단한 방법은 대리자를 만든 다음하는 것입니다 BeginInvoke하는 미래의 어떤 시간에 대기 및 다음 EndInvoke.

public bool Foo(){
    Thread.Sleep(100000); // Do work
    return true;
}

public SomeMethod()
{
    var fooCaller = new Func<bool>(Foo);
    // Call the method asynchronously
    var asyncResult = fooCaller.BeginInvoke(null, null);

    // Potentially do other work while the asynchronous method is executing.

    // Finally, wait for result
    asyncResult.AsyncWaitHandle.WaitOne();
    bool fooResult = fooCaller.EndInvoke(asyncResult);

    Console.WriteLine("Foo returned {0}", fooResult);
}

BackgroundWorker를 사용하십시오. 완료시 콜백을 받고 진행 상황을 추적 할 수 있습니다. 이벤트 인수의 결과 값을 결과 값으로 설정할 수 있습니다.

    public void UseBackgroundWorker()
    {
        var worker = new BackgroundWorker();
        worker.DoWork += DoWork;
        worker.RunWorkerCompleted += WorkDone;
        worker.RunWorkerAsync("input");
    }

    public void DoWork(object sender, DoWorkEventArgs e)
    {
        e.Result = e.Argument.Equals("input");
        Thread.Sleep(1000);
    }

    public void WorkDone(object sender, RunWorkerCompletedEventArgs e)
    {
        var result = (bool) e.Result;
    }

아마도 다음과 같이 메서드를 가리키는 델리게이트를 BeginInvoke 할 수 있습니다.



    delegate string SynchOperation(string value);

    class Program
    {
        static void Main(string[] args)
        {
            BeginTheSynchronousOperation(CallbackOperation, "my value");
            Console.ReadLine();
        }

        static void BeginTheSynchronousOperation(AsyncCallback callback, string value)
        {
            SynchOperation op = new SynchOperation(SynchronousOperation);
            op.BeginInvoke(value, callback, op);
        }

        static string SynchronousOperation(string value)
        {
            Thread.Sleep(10000);
            return value;
        }

        static void CallbackOperation(IAsyncResult result)
        {
            // get your delegate
            var ar = result.AsyncState as SynchOperation;
            // end invoke and get value
            var returned = ar.EndInvoke(result);

            Console.WriteLine(returned);
        }
    }

그런 다음 AsyncCallback으로 보낸 메서드의 값을 사용하여 계속합니다.


값을 반환하려면 비동기 메서드의 EndXXX를 사용해야합니다. EndXXX는 IAsyncResult의 WaitHandle을 사용하는 결과가있을 때까지 기다려야하고 값을 반환해야합니다.

참고 URL : https://stackoverflow.com/questions/6045343/how-to-make-an-asynchronous-method-return-a-value

반응형