1

(我之前过这个问题,但忘记提及一些限制。这是针对带有 Silverlight 4 和 C# 4 的 Windows Phone 7.1 (Mango) 的,它缺少System.Threading.Tasksawait等等。我再次询问希望没有 3rd 的本机解决方案像这样的派对库。)

我正在包装一个库供我自己使用。要获得某个属性,我需要等待一个事件,该事件触发得非常快。我正在尝试将其包装到阻塞调用中。

基本上,我想转

void Prepare()
{
    foo = new Foo();
    foo.Initialized += OnFooInit;
    foo.Start();
}
string Bar
{
    return foo.Bar;  // Only available after OnFooInit has been called.
}

进入这个

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;
}

怎样才能最好地做到这一点?

4

1 回答 1

1

你可以这样做:

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;
}

但是您必须绝对确定 FooInitialized无论发生什么都会调用该事件。否则,您将永远阻塞线程。如果 Foo 有某种错误事件处理程序,请订阅它以避免阻塞您的线程:

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;
}
于 2012-05-07T14:52:46.693 回答