I am in the process of refactoring "synchronous" code (i.e. uses Windows events to wait until some other thread finished doing something) to "asynchronous" code (using delegates to implement a callback mechanism).
In the sync code, I sometimes have local variables that I need to use after the wait is over. When code like that goes async, those local variables are lost (the callback handler can't access them). I can store them as class attributes, but it feels wasteful.
In C++, I use std::bind
to work around this. I just add as many parameters as local variables needed to the callback handler, and bind them when I call the async method. For example, let's say that the async method callback receives an object of type CallbackParam
and the caller uses two local variables of type LocalA
and 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
}
Is there some sort of equivalent to this in C# and VB.NET? Using delegates or something else?
UPDATE: For completeness' sake, here is the C# equivalent of my example based on @lasseespeholt's answer:
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 );
}
}