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

时间:2012-05-07 14:47:39

标签: c# silverlight windows-phone-7 c#-4.0 silverlight-4.0

(我asked this question之前,但忘了提一些约束。这适用于带有Silverlight 4和C#4的Windows Phone 7.1(Mango),它缺少System.Threading.Tasksawait和更多。我再次要求一个没有第三方库的原生解决方案,如this。)

我正在包装一个供我自己使用的库。要获得某个属性,我需要等待一个事件,这个事件很快就会发生。我正试图把它包装成一个阻塞的电话。

基本上,我想转

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

如何最好地完成这项工作?

1 个答案:

答案 0 :(得分: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;
}

但是你必须绝对确定无论发生什么,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;
}