у меня есть следующая проблема:
В асинхронном контексте мне нужно инициализировать поля некоторого пользовательского объекта, прежде чем я смогу продолжить другие операции с ним, поэтому я делаю:
class ContainingObject
{
private CustomObject _co;
SomeMethod()
{
_co = new CustomObject();
_co.InitObjectAsyncCompleted += (s,e) => DoStuff();
_co.InitObjectAsync();
}
}
class CustomObject
{
public string Field1, Field2, Field3, Field4;
public EventHandler InitObjectAsyncCompleted;
public void InitObjectAsync()
{
}
}
Загвоздка в том, что поля также инициализируются через асинхронные вызовы службы WCF, и все они должны быть инициализированы до того, как я вызову событие InitObjectAsyncCompleted.
Существует довольно много этих полей, каждое из которых инициализируется различными вызовами WCF, и подразумевается, что пока я не могу изменить часть WCF, я вижу два пути решения проблемы:
1) Цепные вызовы WCF, поэтому сначала вызов инициализирует первое поле, затем вызывает WCF для инициализации второго поля и т. Д., Прежде чем все поля будут инициализированы, затем я вызываю событие «завершено» в последнем вызове WCF.
public void InitObjectAsync()
{
var proxy = new ProxyFactory.GetCustomObjectProxy;
proxy.GetDataForField1Completed += (s,e) =>
{
Field1 = e.Result;
proxy.GetDataForField2Completed += (s1,e1) =>
{
Field2 = e1.Result;
//keep this up building a chain of events, when Field4 is filled, raise
// InitObjectAsyncCompleted(this, null);
};
proxy.GetDataForField2();
};
proxy.GetDataForField1();
}
2) Так как я знаю, сколько вызовов методов должно быть выполнено, в этом случае я могу сделать счетчик.
public void InitObjectAsync()
{
int counter = 0;
var proxy = new ProxyFactory.GetCustomObjectProxy;
proxy.GetDataForField1Completed += (s,e) =>
{
Field1 = e.Result;
if(counter >= 3)
InitObjectAsyncCompleted(this, null);
else
counter++;
};
proxy.GetDataForField1();
proxy.GetDataForField2Completed += (s,e) =>
{
Field2 = e.Result;
if(counter >= 3)
InitObjectAsyncCompleted(this, null);
else
counter++;
};
proxy.GetDataForField2();
//repeat for all fields
}
Мне не очень нравится ни одно из решений, во-первых, строится довольно большая и плохо читаемая цепочка событий, во-вторых, просто ... грубо - кто-нибудь может предложить более элегантный способ решения этой проблемы?