Я занимаюсь рефакторингом «синхронного» кода (т. Е. Использует события Windows, чтобы ждать, пока какой-либо другой поток не закончит что-то делать), в «асинхронный» код (используя делегаты для реализации механизм обратного вызова).std :: bind эквивалент в C# или VB.NET
В коде синхронизации у меня иногда есть локальные переменные, которые мне нужно использовать после окончания ожидания. Когда такой код идет асинхронно, эти локальные переменные теряются (обработчик обратного вызова не может получить к ним доступ). Я могу хранить их как атрибуты класса, но это кажется расточительным.
В C++ я использую std::bind
, чтобы обойти это. Я просто добавляю столько параметров, сколько локальных переменных, необходимых для обработчика обратного вызова, и связываю их, когда я вызываю метод async. Например, предположим, что обратный вызов асинхронного метода получает объект типа CallbackParam
, и вызывающий абонент использует две локальные переменные типа 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? Использование делегатов или что-то еще?
UPDATE: саке Для полноты, здесь C# эквивалент моего примера на основе ответа @ lasseespeholt в:
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);
}
}
Выглядит хорошо; Я не хотел добавлять состояние в свой класс, но если компилятор делает это, я не против: P Это можно сделать и на VB.NET? (мы говорим .NET 4.0) –
@dario_ramos Я сам не использую VB.Net, но да. C# и VB.Net разделяют большинство функций. Эта страница должна помочь вам использовать lambdas в VB.Net: http://msdn.microsoft.com/en-us/library/bb531253.aspx –