问题
(I asked this question earlier, but had forgotten to mention some constraints. This is for Windows Phone 7.1 (Mango) with Silverlight 4 and C# 4, which lacks System.Threading.Tasks
, await
and more. I'm asking again in hope for a native solution without 3rd party libs like this.)
I'm wrapping a library for my own use. To get a certain property I need to wait for an event, which fires pretty quick. I'm trying to wrap that into a blocking call.
Basically, I want to turn
void Prepare()
{
foo = new Foo();
foo.Initialized += OnFooInit;
foo.Start();
}
string Bar
{
return foo.Bar; // Only available after OnFooInit has been called.
}
Into this
string GetBarWithWait()
{
foo = new Foo();
foo.Initialized += OnFooInit;
foo.Start();
// Wait for OnFooInit to be called and run, but don't know how
return foo.Bar;
}
How could this best be accomplished?
回答1:
You can do something like this:
string GetBarWithWait()
{
foo = new Foo();
using (var mutex = new ManualResetEvent(false))
{
foo.Initialized += (sender, e) =>
{
try
{
OnFooInit(sender, e);
}
finally
{
mutex.Set();
}
}
foo.Start();
mutex.WaitOne();
}
return foo.Bar;
}
But you have to be absolutely certain that Foo will call the Initialized
event no matter what happens. Otherwise, you'll block the thread forever. If Foo has some kind of error event handler, subscribe to it to avoid blocking your thread:
string GetBarWithWait()
{
foo = new Foo();
using (var mutex = new ManualResetEvent(false))
{
foo.Error += (sender, e) =>
{
// Whatever you want to do when an error happens
// Then unblock the thread
mutex.Set();
}
foo.Initialized += (sender, e) =>
{
try
{
OnFooInit(sender, e);
}
finally
{
mutex.Set();
}
}
foo.Start();
mutex.WaitOne();
}
return foo.Bar;
}
来源:https://stackoverflow.com/questions/10484130/turn-event-into-a-async-blocking-call-on-windows-phone-7-c