【发布时间】:2023-04-06 18:09:01
【问题描述】:
我有一个网络项目,它需要从外部肥皂服务更新网页上的统计信息/日志。我决定采用的方法是使用 signalR,通过代码执行服务方法并将结果返回给所有连接的客户端。此代码将连续执行,服务调用之间会有延迟。
我无法将所有部分放在一起,可能是因为我不确定所有部分应该放在哪里!这是我迄今为止所做的粗略细分
class Data { ... }
interface IDataService
{
Task GetDataAsync(TimeSpan interval, CancellationToken cancellationToken, Action<Data> callback);
}
class DataService : IDataService
{
private readonly ExternalService _externalService;
public async Task GetDataAsync(TimeSpan interval, CancellationToken cancellationToken, Action<Data> callback)
{
while (!cancellationToken.IsCancellationRequested)
{
var data = await this._externalService.GetData();
callback(data);
await Task.Delay(interval).ConfigureAwait(false);
}
}
}
以上是从外部服务获取数据并执行回调的逻辑。至于signalR,我唯一做的就是如下
public class DataHub : Hub
{
private readonly IDataService _service;
public DataHub(IDataService service)
{
this._service = service;
}
public async Task GetData()
{
var tenSeconds = new TimeSpan(0, 0, 10);
var token = new CancellationToken();
await _service.GetDataAsync(tenSeconds, token, d =>
{
// signal all connected clients
});
}
}
GetData() 方法可以在客户端连接时调用(如果它尚未运行),并且可以在没有更多客户端连接到集线器时取消令牌。
(潜在的)问题:
- SignalR 集线器不是单例,是吗?我假设它们是在需要时创建并在不再需要时处置(请求已完成)。在这种情况下,我将运行
GetData方法的多个实例(除非我将 DataService 类设为单例/作为单例注入)。 - 集线器不适合执行此操作。集线器应该被视为 MVC/Web Api 控制器吗?所以一个请求进来,集线器处理它,请求完成。故事结束。
- 另一种方法是将集线器传递到数据服务中。然后它可以调用客户端。但我真的不想传递 IHubContext 对象。我想让服务尽可能简单。
- ASP.NET 后台任务在这里更合适吗?
如果有人能指出正确/最佳的方法,将不胜感激!
【问题讨论】:
-
欢迎来到 StackOverflow! 请参阅 "Should questions include “tags” in their titles?",其中的共识是“不,他们不应该”。
标签: c# asp.net signalr async-await