我正在创建一个天气应用程序,用于调查我所提供服务的温度:
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
控制台应用程序退出时会发生什么。
答案 0 :(得分:4)
问题比你想象的要简单:你正在运行BackgroundWorker
,它基本上包含了一个.IsBackground = true
的线程。这样的线程不会使进程保持活动状态 - 当进程退出时它们将自动关闭。当所有非 - 背景线程完成时,该过程将退出。
您的Main
方法启动BackgroundWorker
,但之后不执行任何操作 - Main
退出,并且应用程序已完成。然后BackgroundWorker
会在它到达的任何地方关闭。它运行的代码没有任何问题 - 但应用程序正在关闭而不让它完成。
编辑:如果您想对此进行测试,只需在Console.ReadLine()
的末尾添加Main
- 它就会让应用程序保持活着状态,直到您按下为止输入,所以你应该看到你的线程运行,直到你这样做。
答案 1 :(得分:4)
除了Dan Puzey's answer之外,首先将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();
}
}