【发布时间】:2020-01-09 18:43:13
【问题描述】:
我正在开发一个 Xamarin.Forms Android 应用程序,该应用程序要求手机每 15 秒 ping 一次服务器。我所有的调用都是异步的,它们都具有“await”属性,这包括在 Device.StartTimer 对象中找不到的主类中的所有主要用户函数。例如,在按钮单击、登录和注销时注册数据。对于 15 秒的 ping,我使用的是 Device.StartTimer 函数,我没有遇到太多问题,但有时我确实注意到响应确实重叠,但是我认为“等待”声明会处理响应重叠,因为我读到 Device.StartTimer 在主线程上工作。我做错了什么?有没有更好的方法来管理定时 HTTPClient 调用?
我尝试将 await 属性应用于函数以确保调用不会重叠。有一条关于在主线程上运行的 Device.StartTimer 的注释,所以我认为我的所有异步等待函数都会受到尊重。在主类中包含异步函数。
//Function to ping to the server every 15 seconds
private void StartOfflineTimer()
{
Device.StartTimer(TimeSpan.FromSeconds(15.0), () =>
{
if(timerOffline)
{
Task.Run(async () =>
if(await InformarOfflineAsync(Settings.AccessToken, idRutaOffline))
{
DependencyService.Get<ILogUtils>().GuardarLine("**Device conected..");
}
else
{
DependencyService.Get<ILogUtils>().GuardarLine("**Device disconnected..");
}
);
}
return timerOffline;
});
}
//Default Example of how I handle ALL HTTPClient calls on the app, including calls that are in the main classes, not embedded in a device timer. All of these calls are inside their own public async Task<ExampleObject> function. Once again all of the functions that make these calls have an "await" attribute.
var jsonRequest = await Task.Run(() => JsonConvert.SerializeObject(requestObj));
var httpContent = new StringContent(jsonRequest, Encoding.UTF8, "application/json");
using (var httpClient = new HttpClient())
{
httpClient.Timeout = TimeSpan.FromSeconds(10.0);
var httpResponse = await httpClient.PostAsync(Constants.BaseUrl + "login/validarOffline", httpContent);
ExampleObjectResponseObj exampleObject = new ExampleObjectResponseObj();
var responseContent = await httpResponse.Content.ReadAsStringAsync();
ExampleObjectResponseObj = JsonConvert.DeserializeObject<InformDataResponseObj>(responseContent);
return ExampleObjectResponseObj;
}
HTTPClient 响应可能会重叠,或者有时会重叠并同时发送。
【问题讨论】:
-
你不应该在 using 语句中使用 HTTP 客户端,每次创建新客户端时,套接字都不会被清理,因此这最终会填满你的套接字连接,而是使用静态实例HTTP 客户端,并且只实例化一次。
-
另外,使用 System.Timers.Timer 而不是 Device.StartTimer
-
@Hawkzey 我在另一篇文章中读到,在 using 语句中将其用作 var 以确保每次重新实例化它时都关闭连接。但我会尝试你的建议。这个应用最多可以运行 6 天,你觉得一个 HTTP Client 的静态实例能持续那么久吗?
-
@Jason 感谢您的建议,我在用于设计的功能上没有遇到 Device.StartTimer 的问题(例如,显示 4 秒的验证弹出窗口)。但是您认为 System.Timers.Timer 会处理我的“等待”声明不被尊重吗?
-
@Hawkzey 你能指出一个没有处理套接字的情况吗?
标签: c# xamarin xamarin.forms https xamarin.android