【问题标题】:Loop HTTP Request in Background?在后台循环 HTTP 请求?
【发布时间】:2017-11-03 08:07:11
【问题描述】:

我对使用 HTTP 的东西还很陌生,所以我很困惑每隔几秒左右从 HTTP 地址请求数据的最佳方法是什么。

我使用的 API 有 - 至少据我所知没有 webhook 支持。所以我想更新我的数据的方式会是一种相当粗暴的方式。

我希望这发生在后台,这样 GUI 就不会冻结和无响应。所以我知道我(可能)需要摆弄线程。

我得到的最好结果是使用 async/await 计时器。我不完全确定如何使用它,我让它工作的唯一方法是在它过去后抛出一个异常。如果我不这样做 - 它表示并非所有节点都返回一个值,我什至不能使用 return 这真的让我很困惑。

我应该怎么做?

如果它有任何用处,我正在为一个游戏创建自己的 RCON 工具,该工具通过 HTTP API 提供各种服务器数据 - 但这个 API 的文档非常乏味。

【问题讨论】:

  • 你使用的是.net core还是.net framework?
  • .NET 框架 :)
  • Framework or Core,答案是一样的。您可以通过await Task.Delay() 调用轻松地循环调用该服务。 HttpClient 的方法也是异步的
  • 所以我可以使用while循环和Task.Delay()来防止它冻结程序?但是,这不会向请求的连接发送垃圾邮件吗?或者 await 是否通过 - 从字面上看,等待请求完成来解决这个问题?我对等待/异步的概念还是很陌生,因为我最初来自 Lua,所以这对我来说有点陌生。如果是这样,我应该能够使用秒表来控制它请求数据的时间间隔,对吧?

标签: c# multithreading loops http timer


【解决方案1】:

如果你去 .net core 你可以看到我之前的回答:Start multiple background threads inside Self Hosted ASP.NET Core Microservice

对于 .net 框架,您必须自己做更多的事情。但还是很能干的!

在你的 global.asax 中你有(或者我应该说:应该)有你的依赖注入。比如:

protected void Application_Start()
{
    Bootstrap();

    //and do something more
}

private static void Bootstrap()
{
    var container = new Container();
    container.Register(() => new HttpClient());

    container.RegisterSingleton<IApiCaller, ApiCaller>();
    container.RegisterInitializer<IApiCaller>(ApiCaller=> apicaller.StartCallingAsync());

    // Suppress warnings for HttpClient
    var registration = container.GetRegistration(typeof(HttpClient)).Registration;
    registration.SuppressDiagnosticWarning(DiagnosticType.DisposableTransientComponent, "Dispose is being called by code.");
    registration.SuppressDiagnosticWarning(DiagnosticType.LifestyleMismatch, "Every HttpCient is unique for each dependency.");

    container.Verify();

    GlobalConfiguration.Configuration.DependencyResolver = new SimpleInjectorWebApiDependencyResolver(container);
}

在这种情况下,我让 SimpleInjector 启动我的后台线程来做很多工作。 在 apicaller 中,您可以进行 httpcalls。

类似:

public async Task StartCallingAsync(CancellationToken cancellationToken = (default)CancellationToken)
{
    while(true)
    {
       var response = await _httpClient.GetAsync(url);
       if (response.IsSuccessStatusCode)
       {
           //do work
       }
       await Task.Delay(10000, cancellationToken);
    }
}

对于GetAsync,有一些扩展方法可以将其直接转换为您的对象。

你能用这个吗?

【讨论】:

  • 这不是 .Net Core,而是 ASP.NET Core,它可以与 .Net Core 或 .Net Framework 一起使用
  • 你不需要依赖注入来循环调用HttpClient。你也一无所获。您失去指定 HttpHandlers 的能力。并且 OP 清楚地谈到了 UI 线程,所以这不是 ASP.NET 应用程序
  • 当然你不需要 DI,但它让生活更轻松。但是你让我进入了 UI 线程。但是当然,在 UI 应用程序中,您仍然可以执行 DI,因此,您可以在任何地方实现它:)
  • 最后这个回答问题,只显示DI配置代码。轮询循环在哪里?
猜你喜欢
  • 2012-08-05
  • 2020-05-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-16
  • 2014-02-14
  • 1970-01-01
相关资源
最近更新 更多