繁体   English   中英

我该如何创建一个控制台应用程序,以实现异步/等待

[英]How can I create a console application that utlilitize async/await

我正在创建一个气象应用,该气象应用会根据我提供的服务来查询温度:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;

namespace Weather
{
    class Program
    {
        static BackgroundWorker bgw;

        static void Main(string[] args)
        {
            bgw = new BackgroundWorker();
            bgw.DoWork += bgw_DoWork;
            bgw.RunWorkerAsync();
        }

        static async void bgw_DoWork(object sender, DoWorkEventArgs e)
        {
            Weather bot = new Weather();

            if (bot.IsRunning)
            {
                await bot.Update();
            }
        }
    }

    public class Weather
    {
        public bool IsRunning { get; set; }

        private DateTime lastUpdated;

        public Weather()
        {
            IsRunning = true;

            lastUpdated = DateTime.Now.AddDays(-1);
        }

        public async Task<bool> Update()
        {
            if (lastUpdated < DateTime.Now)
            {
                lastUpdated = DateTime.Now.AddSeconds(30);

                // temperature
                double value = await GetLatestValue("New York");
            }

            return true;
        }

        private async Task<double> GetLatestValue(string city)
        {
            string url = "http://www" + city;

            var client = new WebClient();
            string data = await client.DownloadStringTaskAsync(url);

            return 4.3;
        }
    }
}

这里的问题是它似乎不起作用? GetLatesValue函数只是一点点杂乱无章,仅返回4.3进行测试。

发生的情况是,在await GetLatestValue ,控制台应用程序刚刚退出。

这个问题比您想象的要简单:您正在运行BackgroundWorker ,它基本上包装了一个具有.IsBackground = true的线程。 这样的线程将无法使进程保持活动状态-当进程退出时,它们将自动关闭。 所有后台线程完成后,该过程将退出。

您的Main方法将启动BackgroundWorker ,但随后不执行其他操作Main退出,应用程序完成。 然后, BackgroundWorker会在到达任何时候关闭。 它正在运行的代码没有任何问题-但该应用程序正在关闭而没有完成。

编辑:如果您要测试此,只需在您的Main的末尾放置一个Console.ReadLine() -它可以使应用程序保持活动状态,直到您按Enter键为止,因此您应该看到线程正在运行,直到您这样做为止。

除了Dan Puzey的答案外 ,首先将async void方法分配为BackgroundWorker的事件处理程序没有多大意义。

一旦执行点bgw_DoWork内部的第一个await位置,您的辅助方法bgw_DoWork将返回并且后台线程将完成。 此时bot.Update任务很可能仍将挂起。

您在这里不需要BackgroundWorker 代码可以像这样简单:

static void Main(string[] args)
{
    DoWorkAsync().Wait();
}

static async Task DoWorkAsync()
{
    Weather bot = new Weather();

    if (bot.IsRunning)
    {
        await bot.Update();
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM