[c#] C #에서 비동기 적으로 메서드를 호출하는 방법

누군가가 C #에서 비동기 적으로 메서드를 호출하는 방법을 보여주는 작은 코드 조각을 보여줄 수 있습니까?



답변

action.BeginInvoke ()를 사용하는 경우 어딘가에서 EndInvoke를 호출해야합니다. 그렇지 않으면 프레임 워크가 힙에 대한 비동기 호출의 결과를 보유해야하므로 메모리 누수가 발생합니다.

async / await 키워드를 사용하여 C # 5로 이동하고 싶지 않다면 .Net 4에서 Task Parallels 라이브러리를 사용할 수 있습니다. BeginInvoke / EndInvoke를 사용하는 것보다 훨씬 더 좋고 깔끔한 방법을 제공합니다. 비동기 작업은 잊어 버리세요.

using System.Threading.Tasks;
...
void Foo(){}
...
new Task(Foo).Start();

매개 변수를 사용하는 호출 메서드가있는 경우 대리자를 만들지 않고도 람다를 사용하여 호출을 단순화 할 수 있습니다.

void Foo2(int x, string y)
{
    return;
}
...
new Task(() => { Foo2(42, "life, the universe, and everything");}).Start();

C # 5 async / await 구문이 작업 라이브러리 주변의 구문 설탕 일 뿐이라고 확신합니다 (하지만 긍정적 인 것은 아닙니다).


답변

.Net 4.5부터는 Task.Run을 사용하여 간단히 작업을 시작할 수 있습니다.

void Foo(string args){}
...
Task.Run(() => Foo("bar"));

Task.Run 대 Task.Factory.StartNew


답변

방법은 다음과 같습니다.

// The method to call
void Foo()
{
}


Action action = Foo;
action.BeginInvoke(ar => action.EndInvoke(ar), null);

물론 Action메서드에 다른 서명이있는 경우 다른 유형의 대리자 로 대체해야합니다.


답변

MSDN 문서 Async 및 Await를 사용한 비동기 프로그래밍 (Asynchronous Programming with Async and Await)을 확인하십시오. .NET 4.5에 추가되었습니다.

링크의 예제 코드 스 니펫 ( 이 MSDN 샘플 코드 프로젝트 자체 ) :

// Three things to note in the signature: 
//  - The method has an async modifier.  
//  - The return type is Task or Task<T>. (See "Return Types" section.)
//    Here, it is Task<int> because the return statement returns an integer. 
//  - The method name ends in "Async."
async Task<int> AccessTheWebAsync()
{ 
    // You need to add a reference to System.Net.Http to declare client.
    HttpClient client = new HttpClient();

    // GetStringAsync returns a Task<string>. That means that when you await the 
    // task you'll get a string (urlContents).
    Task<string> getStringTask = client.GetStringAsync("http://msdn.microsoft.com");

    // You can do work here that doesn't rely on the string from GetStringAsync.
    DoIndependentWork();

    // The await operator suspends AccessTheWebAsync. 
    //  - AccessTheWebAsync can't continue until getStringTask is complete. 
    //  - Meanwhile, control returns to the caller of AccessTheWebAsync. 
    //  - Control resumes here when getStringTask is complete.  
    //  - The await operator then retrieves the string result from getStringTask. 
    string urlContents = await getStringTask;

    // The return statement specifies an integer result. 
    // Any methods that are awaiting AccessTheWebAsync retrieve the length value. 
    return urlContents.Length;
}

인용 :

AccessTheWebAsyncGetStringAsync를 호출하고 완료를 기다리는 사이에 수행 할 수있는 작업이없는 경우 다음 단일 문에서 호출 및 대기하여 코드를 단순화 할 수 있습니다.

string urlContents = await client.GetStringAsync();

자세한 내용은 링크에 있습니다.


답변

public partial class MainForm : Form
{
    Image img;
    private void button1_Click(object sender, EventArgs e)
    {
        LoadImageAsynchronously("http://media1.santabanta.com/full5/Indian%20%20Celebrities(F)/Jacqueline%20Fernandez/jacqueline-fernandez-18a.jpg");
    }

    private void LoadImageAsynchronously(string url)
    {
        /*
        This is a classic example of how make a synchronous code snippet work asynchronously.
        A class implements a method synchronously like the WebClient's DownloadData(…) function for example
            (1) First wrap the method call in an Anonymous delegate.
            (2) Use BeginInvoke(…) and send the wrapped anonymous delegate object as the last parameter along with a callback function name as the first parameter.
            (3) In the callback method retrieve the ar's AsyncState as a Type (typecast) of the anonymous delegate. Along with this object comes EndInvoke(…) as free Gift
            (4) Use EndInvoke(…) to retrieve the synchronous call’s return value in our case it will be the WebClient's DownloadData(…)’s return value.
        */
        try
        {
            Func<Image> load_image_Async = delegate()
            {
                WebClient wc = new WebClient();
                Bitmap bmpLocal = new Bitmap(new MemoryStream(wc.DownloadData(url)));
                wc.Dispose();
                return bmpLocal;
            };

            Action<IAsyncResult> load_Image_call_back = delegate(IAsyncResult ar)
            {
                Func<Image> ss = (Func<Image>)ar.AsyncState;
                Bitmap myBmp = (Bitmap)ss.EndInvoke(ar);

                if (img != null) img.Dispose();
                if (myBmp != null)
                    img = myBmp;
                Invalidate();
                //timer.Enabled = true;
            };
            //load_image_Async.BeginInvoke(callback_load_Image, load_image_Async);             
            load_image_Async.BeginInvoke(new AsyncCallback(load_Image_call_back), load_image_Async);             
        }
        catch (Exception ex)
        {

        }
    }
    protected override void OnPaint(PaintEventArgs e)
    {
        if (img != null)
        {
            Graphics grfx = e.Graphics;
            grfx.DrawImage(img,new Point(0,0));
        }
    }


답변