等待事情发生 - 异步或同步模式? [英] Waiting for something to happen - asynchronous or synchronous model?

查看:93
本文介绍了等待事情发生 - 异步或同步模式?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这样的方法 WaitForReaderArrival 这是象下面这样: (运行所有的时间等待读者到达)

 公共无效WaitForReaderArrival()
        {
            做
            {
                如果(ReaderArrived())
                {
                    打破;
                }

                System.Threading.Thread.Sleep(1000);
            }而(ReaderArrived()==假);
        }
 

和我正在等待为读者使用到,

 等待Task.Run(新动作(WaitForReaderArrival));
 如果(ReaderArrived())
 {
      //这里引发一个ReaderArrived!
    ..//blah等等
 }
 

我的一个同事问我改变上述行只是

  WaitForReaderArrival();
 如果(ReaderArrived())
 {
    //这里引发一个ReaderArrived!
    ..//blah等等
 }
 

现在的问题是:

  1. 是,我采取了上述异步模式是不是真的有用吗?为什么她问我到该行变为正常的同步方法仍然是一个问题,对我来说。

  2. 在什么上面是正确的方式来等待事情发生,然后继续吗?

解决方案
  

时,我采取了上述异步模式是不是真的有用吗?   为什么她问我到该行更改为正常的同步方法   仍然是一个问题,对我来说。

您使用的是code是忙等待循环,这是轮询东西节流。 如果你没有改变的通知得到任何其他方式,你可以卸载这个循环到池中的线程,你正在做的已经与计谋Task.Run ,或者更好的是,使用 Task.Delay

 公共异步任务WaitForReaderArrivalAsync()
{
    而(!ReaderArrived())
    {
        等待Task.Delay(1000).ConfigureAwait(假);
    }
}
 

  

我的一位同事问我改变了上面的行...什么的   以上是正确的方式来等待事情发生,然后   继续吗?

您的同事是错误的。如果你打电话给原来的 WaitForReaderArrival 而不包装它等待Task.Run ,或拨打上面所提出的版本 WaitForReaderArrivalAsync()。等待(),你会阻塞UI线程。为了保持UI线程的消息循环的功能,你应该让你的code 异步一路

  //顶级事件处理程序
异步无效Button_Click(对象发件人,EventArgs的)
{
    等待WaitForReaderArrivalAsync();
    的MessageBox.show(ReaderArrived!);
}
 

这是调用它的正确途径。从概念上讲,它非常类似于检查 ReaderArrived 在一个计时器事件,但异步/计谋为您提供方便的线性伪同步code流量。

请注意,有一种流行的反模式这确实忙于的DoEvents 等,以保持用户界面响应,有效地创建一个嵌套的消息循环在UI线程上:

 公共无效WaitForReaderArrival()
{
    而(!ReaderArrived())
    {
        Application.DoEvents();
        System.Threading.Thread.Sleep(100);
    }
}
 

这样做是错误的:保持你的UI响应和Application.DoEvents的危险的。

I have this method WaitForReaderArrival which is like below: (Runs all the time waiting for a reader to arrive)

        public void WaitForReaderArrival()
        {
            do
            {
                if (ReaderArrived())
                {
                    break;
                }

                System.Threading.Thread.Sleep(1000);
            } while (ReaderArrived() == false);
        }

And I am awaiting for the reader to arrive using,

 await Task.Run(new Action(WaitForReaderArrival));
 if (ReaderArrived())
 {
      //Raise an ReaderArrived here!
    ..//blah blah
 }

One of my co-worker asked me to change the above line just to

 WaitForReaderArrival(); 
 if (ReaderArrived())
 {
    //Raise an ReaderArrived here!
    ..//blah blah
 }

The question is:

  1. Is the asynchronous model that I adopted above is not really useful? Why she asked me to change that line to normal synchronous methodology is still a question to me.

  2. What in the above is the right way to wait for something to happen and then proceed?

解决方案

Is the asynchronous model that I adopted above is not really useful? Why she asked me to change that line to normal synchronous methodology is still a question to me.

The code you're using is a slightly improved version of the busy waiting loop, which is polling for something with throttling. If you don't have any other ways of getting notified of the change, you can offload this loop to a pool thread as you're doing already with await Task.Run, or better yet, use Task.Delay:

public async Task WaitForReaderArrivalAsync()
{
    while (!ReaderArrived())
    {
        await Task.Delay(1000).ConfigureAwait(false);
    }
}

One of my co-worker asked me to change the above line... What in the above is the right way to wait for something to happen and then proceed?

Your coworker is wrong. If you call your original WaitForReaderArrival without wrapping it with await Task.Run, or call the version proposed above as WaitForReaderArrivalAsync().Wait(), you will block the UI thread. To keep the UI thread message loop functional, you should make your code "Async All the Way":

// top-level event handler
async void Button_Click(object sender, EventArgs e)
{
    await WaitForReaderArrivalAsync();
    MessageBox.Show("ReaderArrived!");
}

That's the right way of calling it. Conceptually, it is very similar to checking ReaderArrived upon a timer event, but async/await gives you convenient linear pseudo-synchronous code flow.

Note, there is a popular anti-pattern which does busy waiting with DoEvents to keep the UI responsive, effectively creating a nested message loop on the UI thread:

public void WaitForReaderArrival()
{
    while (!ReaderArrived())
    {
        Application.DoEvents();
        System.Threading.Thread.Sleep(100);
    }
}

Doing so is wrong: Keeping your UI Responsive and the Dangers of Application.DoEvents.

这篇关于等待事情发生 - 异步或同步模式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆