C# ForecastIOPortable lib in WPF application with Timer

本文关键字:application with Timer WPF in ForecastIOPortable lib | 更新日期: 2023-09-27 18:30:42

我正在尝试使用ForecastIOPortable库获取天气信息。我有一个在控制台应用程序中没有问题的方法,在 WPF 应用程序中也是如此。

ForecastApi api = new ForecastApi("XXXX");
var forecast = api.GetWeatherDataAsync(XXXX, XXXX);
var results = forecast.Result;
int tempC = (int)(5.0 / 9.0 * (results.Currently.Temperature - 32));

当我尝试使用计时器的滴答声调用该方法时,会出现问题,程序冻结并且 VS 不显示有关异常的信息。当我检查断点时,我得到的结果不会更改并且所有时间都具有 value=null 的信息。问题的原因是什么,如何处理?

C# ForecastIOPortable lib in WPF application with Timer

您正在使用异步进程,因此您将获得任务而不是结果。

在控制台应用程序中,通常必须 。Wait() 在填充结果之前解析任务。 最好使用 WPF 应用程序进行测试,您可以在其中等待 GetWeatherDataAsync 方法。

处理它的最佳方法可能是将计时器包装在一个类中并传入各个位。

你可以试试这个

public class ForecastApiAsyncTimer : IDisposable
{
    private ForecastApi _api;
    private Timer _timer;
    public ForecastApiAsyncTimer(Timer timer, ForecastApi forecastApi)
    {
        if (timer == null)
            throw new ArgumentNullException("timer");
        if (forecastApi == null)
            throw new ArgumentNullException("forecastApi");
        _api = forecastApi;
        _timer = timer;
        _timer.Elapsed += _timer_Elapsed;
    }
    public ForecastApiAsyncTimer(double interval, ForecastApi forecastApi)
    {
        if (forecastApi == null)
            throw new ArgumentNullException("forecastApi");
        _api = forecastApi;
        _timer = new Timer(interval);
        _timer.Elapsed += _timer_Elapsed;
    }
    public void Start()
    {
        _timer.Start();
    }
    public void Stop()
    {
        _timer.Stop();
    }
    protected async virtual Task<int> TimerElapsedTask()
    {
        var forecast = await _api.GetWeatherDataAsync(40.7505045d, -73.9934387d);
        int tempC = (int)(5.0 / 9.0 * (forecast.Currently.Temperature - 32));
        return tempC;
    }
    async void _timer_Elapsed(object sender, ElapsedEventArgs e)
    {
        int result = await TimerElapsedTask();
        // do something with result.
    }
    ~ForecastApiAsyncTimer()
    {
        Dispose(false);
    }
    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }
    protected virtual void Dispose(bool disposing)
    {
        if (!disposing || _timer == null)
            return;
        _timer.Dispose();
        _timer = null;
    }
}

用法示例 1.

static void Main(string[] args)
{
    string apiKey = "yourApiKey";
    ForecastApi api = new ForecastApi(apiKey);
    using (var forecastTimer = new ForecastApiAsyncTimer(5000, api))
    {
        forecastTimer.Start();
        while (!Console.KeyAvailable)
        {

        }
    }
}

示例用法 2:

static void Main(string[] args)
{
    string apiKey = "yourApiKey";
    ForecastApi api = new ForecastApi(apiKey);
    Timer timer = new Timer(5000);
    var forecastTimer = new ForecastApiAsyncTimer(timer, api);
    forecastTimer.Start();
    while (!Console.KeyAvailable)
    {

    }
}