2017-02-06 16 views
1
public static void Connect(EndPoint remoteEP, Socket client) { 
    client.BeginConnect(remoteEP, 
     new AsyncCallback(ConnectCallback), client); 

    connectDone.WaitOne(); 
} 

private static void ConnectCallback(IAsyncResult ar) { 
    try { 
     // Retrieve the socket from the state object. 
     Socket client = (Socket) ar.AsyncState; 

     // Complete the connection. 
     client.EndConnect(ar); 

     Console.WriteLine("Socket connected to {0}", 
      client.RemoteEndPoint.ToString()); 

     // Signal that the connection has been made. 
     connectDone.Set(); 
    } catch (Exception e) { 
     Console.WriteLine(e.ToString()); 
    } 
} 

こんにちは、私は上の2つの関数の質問があります 関数 "client.BeginConnect"では、なぜConnectCallbackのパラメータが空ですか? ConnectCallback関数にはパラメータ(IAsyncResult ar)があります。 BeginConnectはこのパラメータを呼び出すことはありません。誰が私の質問に答えることができますか?なぜこのパラメータは空ですか?

+2

「AsyncCallback」がメソッドの代理人を受け入れると仮定します。完了したら呼び出します。メソッド 'ConnectCallback'を呼び出し、それが生成した' IAsyncResult'を渡します。 – Equalsk

+0

これはすべて "Under the hood"で終了し、非同期アクションを完了した後、 'ConnectCallback'メソッドを呼び出し、生成された' IAsyncResult'を渡します。これには、この特定の非同期操作に関する情報が含まれています。また、 'AsyncState'として指定された、あなたのケースの' client'パラメータも含まれています。 –

答えて

2

BeginConnectメソッドは、非同期タスクが終了したときに呼び出される第2パラメータとして委譲参照が渡されることを想定しています。パラメータをConnectCallbackに指定した場合は、代わりにメソッド呼び出しとして評価され、その結果はvoid(voidメソッドなので)になるため、コードはコンパイルされません。

つまり

、あなたがこのような方法がある場合:

void DoStuff(int parameter) 
{ ... } 

を次にDoStuffから参照を取得違いがある:

呼び出す
// method variable will get the reference to the DoStuff method 
Action<int> method = new Action<int>(DoStuff); 

// invoking the delegate will invoke the actual DoStuff method 
method(7); 

方法(評価する):

// this will simply evaluate DoStuff 
DoStuff(7); 

非同期メソッドに渡されるデリゲートは、コールバックと呼ばれます。非同期メソッドは、ジョブを終了すると非同期メソッドを呼び出すためです。コールバックデリゲートに渡される実際のパラメータは、その場合はメソッドによって作成されたasyncメソッドから渡されるか、または以前の方法で渡されます。 BeginConnectの場合

、あなたもSocket.BeginConnectはボンネットの下に、これと機能的に似た何かをすることを意味し、コールバックに渡される実際のパラメータであるstate PARAMTERを渡す:

void BeginConnect(EndPoint remoteEP, AsyncCallback callback, object state) 
{ 
    // create an async task and return to called immediately 
    Task.Run(() => 
    { 
     // do some stuff on a background thread 
     .... 

     // call `callback` when done, and pass the `state` parameter 
     // through the `IAsyncResult` parameter 
     var result = new ConnectAsyncResult(..., state, ...); 
     callback(result); 
    }); 
} 

そして、コールバックメソッドの責任は、渡されたパラメータのEndInvokeを呼び出して操作を終了することです。

このパターンを使用すると、呼び出し元コードが実際に呼び出した人に関するすべての必要な情報(「状態」)を使用して、実行を継続し、通知を受け取ることができます。

0

AsyncCallbackは、パラメータとしてIAsyncResultを持つコールバックメソッドを実行するデリゲートです。あなたは説明hereを見ることができます。したがって、基本的にはIAsyncResultをパラメータとして受け入れるメソッドを提供する必要があります。AsyncCallback代理人が呼び出すことができるようにする必要があります。ConnectCallbackメソッド

関連する問題