在 Windows Phone 7 (C#) 上将事件转换为异步/阻止调用

本文关键字:异步 转换 调用 事件 Phone Windows | 更新日期: 2023-09-27 18:33:20

(我之前问过这个问题,但忘了提到一些约束。这是针对带有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;
}

如何才能最好地做到这一点?

在 Windows Phone 7 (C#) 上将事件转换为异步/阻止调用

你可以做这样的事情:

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

但你必须绝对确定,无论发生什么,Foo都会调用Initialized事件。否则,您将永远阻塞该线程。如果 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;
}