Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用信号器实现服务器端事件_C#_Asp.net Mvc_Events_Signalr - Fatal编程技术网

C# 使用信号器实现服务器端事件

C# 使用信号器实现服务器端事件,c#,asp.net-mvc,events,signalr,C#,Asp.net Mvc,Events,Signalr,我目前正在为我们当前的一些工具构建一些signar概念验证,我正在寻找实现某种服务器端事件平台的最佳方法。我们的很多工具都是非常程序化和简单的,但我确实有一些长期运行的任务,我希望改变 我们的报告平台就是这样一个例子。我们的webapp内置了一个内部的基本报告系统,可以执行一些预构建的报告。运行这些报告可能需要30秒到5分钟。运行它们的方式是向服务器发送带有所需参数的请求。一旦服务器接收到请求,它就会将唯一的guid返回给客户端。然后,服务器启动报表运行程序,它基本上只是一个小的未等待的异步方法

我目前正在为我们当前的一些工具构建一些signar概念验证,我正在寻找实现某种服务器端事件平台的最佳方法。我们的很多工具都是非常程序化和简单的,但我确实有一些长期运行的任务,我希望改变

我们的报告平台就是这样一个例子。我们的webapp内置了一个内部的基本报告系统,可以执行一些预构建的报告。运行这些报告可能需要30秒到5分钟。运行它们的方式是向服务器发送带有所需参数的请求。一旦服务器接收到请求,它就会将唯一的guid返回给客户端。然后,服务器启动报表运行程序,它基本上只是一个小的未等待的异步方法,用于执行某些功能并在数据库中设置报表的状态

目前,有一种客户端轮询机制,它反复向服务器询问报告的状态,一旦报告运行,它就会获取并显示报告。我已经改变了ReportRunner方法,并将其更改为启动服务器端轮询机制,该机制在不同线程上连续检查数据库。报告完成后,它会调用我们的信号集线器并将其广播给客户端

我正在尝试找到一种方法来修改服务器,而不是轮询以获取状态,而是以某种方式连接到报表运行程序,然后在完成后调用signalR hub

我目前的想法是在运行程序上创建一个可选参数,该参数接受一个实现简单接口的对象,
IBasicEvent
。该界面可能看起来像:

public interface IBasicEvent
{
    void OnSuccess();
    void OnError();
    void Complete();
}

从那里,我可以在我的WebUI项目中实现该接口,并简单地将其传递到另一个项目中的报表运行程序中。这似乎相对简单,但我也看到了一些关于可能使用委托的信息,几乎与javascript中的回调一样。我真的不知道最好的方法是什么。

我设法用C#的委托和事件处理程序得到了一个非常酷的概念证明,它似乎可以处理我需要的一切。这里是基本设置,去掉了不相关的逻辑

在我的报告中:

public class ReportRunner
{
    public delegate Task RunCompleteHandler(ReportRunner runner, ReportStatusEventArgs eventArgs);
    public event RunCompleteHandler RunComplete;

    protected void OnRunComplete(ReportRunner runner, ReportStatusEventArgs eventArgs)
    {
        RunComplete?.Invoke(runner, eventArgs);
    }

    private async Task ExecuteReport(FilterSet filters, Guid guid)
    {
        try
        {
            // run the report
        }
        catch (Exception ex)
        {
            // log and set the report to error status
        }
        finally
        {
            var status = _reportLogic.GetReportRunStatus(guid);
            var eventArgs = new ReportStatusEventArgs(status);

            OnRunComplete(this, eventArgs);
        }
    }
}

public class ReportStatusEventArgs : EventArgs
{
    public readonly ReportRunStatus ReportRunStatus;
    public ReportStatusEventArgs(ReportRunStatus reportRunStatus)
    {
        ReportRunStatus = reportRunStatus;
    }
}
在我的控制器中:

public async Task<IActionResult> Run(FiltersRequest request)
{
    // basic checks omitted
    var factory = new ReportFactory();
    var reportModel = factory.CreateReport(reportType);
    var runner = new ReportRunner(reportModel, _contexts);
    var eventHandler = new ReportRunnerSubscriber(_reportHub, HttpContext.User.Identity.Name);
    eventHandler.Subscribe(runner);

    var guid = await runner.Run(filterSet);

    return Json(guid);
}
公共异步任务运行(FiltersRequest请求)
{
//省略基本检查
var factory=new ReportFactory();
var reportModel=factory.CreateReport(reportType);
var runner=new ReportRunner(reportModel,_上下文);
var eventHandler=new ReportRunnerSubscriber(_reportHub,HttpContext.User.Identity.Name);
订阅(运行程序);
var guid=wait runner.Run(filterSet);
返回Json(guid);
}
还有我的订户类

public class ReportRunnerSubscriber
{
    private readonly IHubContext<ReportHub> _reportHub;
    private readonly string _userId;

    public ReportRunnerSubscriber(IHubContext<ReportHub> reportHub, string userId)
    {
        _reportHub = reportHub;
        _userId = userId;
    }

    public void Subscribe(ReportRunner reportRunner)
    {
        reportRunner.RunComplete += NotifySubscribers;
    }

    public async Task NotifySubscribers(ReportRunner reportRunner, ReportStatusEventArgs eventArgs)
    {
        var status = eventArgs.ReportRunStatus;
        status.ReportRuns = null;
        await _reportHub.Clients.User(_userId).SendAsync("ReportComplete", status);
    }
}
公共类ReportRunnerSubscriber
{
私有只读IHubContext\u reportHub;
私有只读字符串_userId;
public ReportRunnerSubscriber(IHubContext reportHub,字符串用户ID)
{
_reportHub=reportHub;
_userId=userId;
}
公开作废订阅(ReportRunner ReportRunner)
{
reportRunner.RunComplete+=NotifySubscribers;
}
公共异步任务NotifySubscribers(ReportRunner ReportRunner、ReportStatusEventArgs eventArgs)
{
var status=eventArgs.ReportRunStatus;
status.ReportRuns=null;
wait _reportHub.Clients.User(_userId).SendAsync(“ReportComplete”,status);
}
}