[Отказ от ответственности - этот код упрощен (намного) для легкого чтения, и я знаю, что он не соответствует обычным стандартам кода]
Мою проблему можно увидеть в коде ниже. В основном у меня есть вызывающий абонент, который анализирует объект. Мне нужно дождаться завершения подкомпонента, о чем сигнализирует событие, прежде чем вернуть значение из того, что основано на каком-то значении подкомпонента.
Вопрос в том, какой шаблон предпочтительнее для подобных ситуаций (конечно, фактическое решение было бы очень кстати).
Я экспериментировал с разными вещами вокруг TaskCompletionSource и т. д., но боюсь, что мое понимание отстает от того, чтобы найти (желательно) элегантное решение. Надеюсь, вы можете помочь.
public class AsyncEventTest
{
// This is performed one a single (UI) thread. The exception to this is
// a.B that might - at the calling time - get a asycronious update from the backend.
// The update is syncronized into the calling context so Task.Wait etc. will effectivly
// deadlock the flow.
public static string CallMe(A a)
{
if (a.B.State != State.Ready)
{
// wait for a.B.State == State.Ready ... but how ...
// await MagicMethod() ???;
}
// only execute this code after a.b.State == State.Ready
return a.B.Text;
}
}
public class A
{
public B B { get; set; }
}
public class B
{
public State State { get; private set; }
public event Action StateChanged;
public string Text { get; }
}
public enum State { Ready, Working, }
РЕДАКТИРОВАТЬ - пример того, что я пробовал. Интересно, является ли что-то подобное приемлемым подходом (или даже работает ли он)?
public class AsyncEventTest2
{
public static string CallMe(A a)
{
return CallMe1(a).Result;
}
public async static Task<string> CallMe1(A a)
{
await CallMe2(a);
return a.B.Text;
}
public static Task CallMe2(A a)
{
TaskCompletionSource<string> tcs = new TaskCompletionSource<string>();
if (a.B.State != State.Ready)
{
a.B.StateChanged += () =>
{
if (a.B.State == State.Ready)
tcs.SetResult(a.B.Text);
};
}
else
{
tcs.SetResult(a.B.Text);
}
return tcs.Task;
}
}
ManualResetEvent
). - person Henk Holterman   schedule 09.01.2013