「同期」コード (つまり、Windows イベントを使用して、他のスレッドが何かを完了するまで待機する) を「非同期」コード (デリゲートを使用してコールバック メカニズムを実装する) にリファクタリングしています。
同期コードには、待機が終了した後に使用する必要があるローカル変数が含まれていることがあります。そのようなコードが非同期になると、それらのローカル変数は失われます (コールバック ハンドラーはそれらにアクセスできません)。クラス属性として保存できますが、もったいない気がします。
C++ では、std::bind
これを回避するために使用します。コールバック ハンドラーに必要なローカル変数と同じ数のパラメーターを追加し、非同期メソッドを呼び出すときにそれらをバインドします。たとえば、非同期メソッドのコールバックが 型のオブジェクトを受け取り、呼び出し元が型とCallbackParam
の 2 つのローカル変数を使用するとします。LocalA
LocalB
void AsyncClass::MethodWhichCallsAsyncMethod(){
LocalA localVarA;
LocalB localVarB;
// OnAsyncMethodDone will need localVarA and localVarB, so we bind them
AsyncMethod( std::bind( &AsyncClass::OnAsyncMethodDone, this, std::placeholders::_1, localVarA, localVarB ) );
}
void AsynClass::AsyncMethod( std::function<void(CallbackParam)> callback ){
CallbackParam result;
//Compute result...
if( callback )
callback( result );
}
void AsyncClass::OnAsyncMethodDone( CallbackParam p, LocalA a, LocalB b ){
//Do whatever needs to be done
}
C# と VB.NET でこれに相当するものはありますか? デリゲートなどを使用していますか?
更新: 完全を期すために、@lasseespeholt の回答に基づいた私の例に相当する C# を次に示します。
using System;
public class AsyncClass {
public void MethodWhichCallsAsyncMethod() {
var a = new LocalA();
var b = new LocalB();
//Anonymous callback handler (equivalent to AsyncClass::OnAsyncMethodDone)
Action<CallbackParam> callback = result => {
//Do what needs to be done; result, a and b can be accessed
};
AsyncMethod( callback );
}
private void AsyncMethod( Action<CallbackParam> callback ) {
var result = new CallbackParam();
//Compute result...
if( callback != null )
callback( result );
}
}