Uma*_*air 5 c# asp.net async-await signalr
我有一个Web项目,需要从外部soap服务更新网页上的统计信息/日志.我决定采用的方法是使用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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
所以上面是从外部服务获取数据并执行回调的逻辑.至于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
});
}
}
Run Code Online (Sandbox Code Playgroud)
GetData()可以在客户端连接时调用该方法(如果它尚未运行),并且当没有其他客户端连接到集线器时可以取消该令牌.
(潜在问题:
GetData运行该方法的多个实例(除非我将DataService类设为单例/注入为单例).如果有人能指出我正确/最好的方法,将不胜感激!
我已经通过使用 System.Web.Hosting 命名空间中的 IRegisteredObject 接口设法解决了这个问题。所以我的预定任务是:
public class DataTask : IRegisteredObject
{
private readonly IGlobalData _global;
private readonly IDataService _service;
private readonly IHubContext _hub;
private Timer _timer;
public DataTask(IGlobalData global, IDataService service, IHubContext hub)
{
this._global = global;
this._service = service;
this._hub = hub;
var interval = new TimeSpan(0, 0, 10);
this._timer = new Timer(updateClients, null, TimeSpan.Zero, interval);
// register this task with asp.net
HostingEnvironment.RegisterObject(this);
}
public void Stop(bool immediate)
{
_timer.Dispose();
HostingEnvironment.UnregisterObject(this);
}
private async void updateClients(object state)
{
var result = await this._service.GetData();
// call the hub
this._hub.Clients.All.updateData(result);
}
}
Run Code Online (Sandbox Code Playgroud)
我确实遇到了很多问题!但这是由于我用于 signalR 的自定义依赖解析器(问题是客户端 js 函数没有从此任务中调用)。一旦解决了这个问题,一切都会按预期进行。
| 归档时间: |
|
| 查看次数: |
1546 次 |
| 最近记录: |