Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/293.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/flash/4.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# 托管服务.Net核心的集成测试`_C#_Asp.net Core_.net Core_Mstest_Asp.net Core Hosted Services - Fatal编程技术网

C# 托管服务.Net核心的集成测试`

C# 托管服务.Net核心的集成测试`,c#,asp.net-core,.net-core,mstest,asp.net-core-hosted-services,C#,Asp.net Core,.net Core,Mstest,Asp.net Core Hosted Services,我有一个QueueTask托管服务(.Net Core的新后台服务),我想测试它。我的queuedHosted服务如下所示: public QueuedHostedService(IServiceProvider serviceProvider, IBackgroundTaskQueue taskQueue, ILoggerFactory loggerFactory) { TaskQueue = taskQueue; _logger = loggerFactory.CreateL

我有一个QueueTask托管服务(.Net Core的新后台服务),我想测试它。我的queuedHosted服务如下所示:

public QueuedHostedService(IServiceProvider serviceProvider, IBackgroundTaskQueue taskQueue, ILoggerFactory loggerFactory)
{
    TaskQueue = taskQueue;
    _logger = loggerFactory.CreateLogger<QueuedHostedService>();
    _serviceProvider = serviceProvider;
}

protected async override Task ExecuteAsync(CancellationToken stoppingToken)
{
    using (var scope = _serviceProvider.CreateScope())
    {
        while (false == stoppingToken.IsCancellationRequested)
        {
            var workItem = await TaskQueue.DequeueAsync(stoppingToken);
            try
            {
                await workItem(scope.ServiceProvider, stoppingToken);
            }
            catch (Exception ex)
            {
                this._logger.LogError(ex, $"Error occurred executing {nameof(workItem)}.");
            }
        }
    }
}
public QueuedHostedService(IServiceProvider服务提供程序、IBackgroundTaskQueue任务队列、ILoggerFactory loggerFactory)
{
TaskQueue=TaskQueue;
_logger=loggerFactory.CreateLogger();
_服务提供者=服务提供者;
}
受保护的异步覆盖任务ExecuteAsync(CancellationToken stoppingToken)
{
使用(var scope=\u serviceProvider.CreateScope())
{
while(false==stoppingToken.IsCancellationRequested)
{
var workItem=wait TaskQueue.DequeueAsync(stoppingToken);
尝试
{
等待工作项(scope.ServiceProvider,stoppingToken);
}
捕获(例外情况除外)
{
此.u logger.LogError(例如,$”执行{nameof(workItem)}时发生错误);
}
}
}
}
它只是从队列中读取任务,并在任务进入时执行它们。我已经验证了托管服务是否正在生产中工作。我写了一个测试,就像这样:

[TestMethod]
public async Task Verify_Hosted_Service_Executes_Task()
{
    IServiceCollection services = new ServiceCollection();
    services.AddSingleton<ILoggerFactory, NullLoggerFactory>();
    services.AddHostedService<QueuedHostedService>();
    services.AddSingleton<IBackgroundTaskQueue, BackgroundTaskQueue>();
    var serviceProvider = services.BuildServiceProvider();

    var backgroundQueue = serviceProvider.GetService<IBackgroundTaskQueue>();

    var isExecuted = false;
    backgroundQueue.QueueBackgroundWorkItem(async (sp, ct) => {
        isExecuted = true;
    });

    await Task.Delay(10000);
    Assert.IsTrue(isExecuted);
}
[TestMethod]
公共异步任务验证\u托管的\u服务\u执行\u任务()
{
IServiceCollection服务=新的ServiceCollection();
services.AddSingleton();
services.AddHostedService();
services.AddSingleton();
var serviceProvider=services.BuildServiceProvider();
var backgroundQueue=serviceProvider.GetService();
var isExecuted=false;
backgroundQueue.QueueBackgroundWorkItem(异步(sp、ct)=>{
isExecuted=真;
});
等待任务。延迟(10000);
Assert.IsTrue(已执行);
}
然而,我的回电从未被击中。如何让我的任务在后台服务上执行

编辑

我在模仿这家初创公司,并假设后台服务可以正常工作, 但显然我的服务从未开始过


托管服务是如何从.Net Core启动的?

托管服务由框架启动,作为Web主机启动过程的一部分

// Fire IHostedService.Start
await _hostedServiceExecutor.StartAsync(cancellationToken).ConfigureAwait(false);

通过
HostedServiceExecutor
,它将收集所有注册的
IHostedService
,枚举它们并依次启动它们

public HostedServiceExecutor(ILogger<HostedServiceExecutor> logger, IEnumerable<IHostedService> services)
{
    _logger = logger;
    _services = services;
}

public async Task StartAsync(CancellationToken token)
{
    try
    {
        await ExecuteAsync(service => service.StartAsync(token));
    }
    catch (Exception ex)
    {
        _logger.ApplicationError(LoggerEventIds.HostedServiceStartException, "An error occurred starting the application", ex);
    }
}
公共托管服务执行器(ILogger记录器,IEnumerable服务)
{
_记录器=记录器;
_服务=服务;
}
公共异步任务StartAsync(CancellationToken令牌)
{
尝试
{
等待ExecuteAsync(service=>service.StartAsync(令牌));
}
捕获(例外情况除外)
{
_logger.ApplicationError(LoggerEventIds.HostedServiceStartException,“启动应用程序时出错”,ex);
}
}

但是,由于您要自己测试托管服务,因此您必须充当框架并自己启动服务

[TestMethod]
public async Task Verify_Hosted_Service_Executes_Task() {
    IServiceCollection services = new ServiceCollection();
    services.AddSingleton<ILoggerFactory, NullLoggerFactory>();
    services.AddHostedService<QueuedHostedService>();
    services.AddSingleton<IBackgroundTaskQueue, BackgroundTaskQueue>();
    var serviceProvider = services.BuildServiceProvider();

    var service = serviceProvider.GetService<IHostedService>() as QueuedHostedService;

    var backgroundQueue = serviceProvider.GetService<IBackgroundTaskQueue>();

    await service.StartAsync(CancellationToken.None);

    var isExecuted = false;
    backgroundQueue.QueueBackgroundWorkItem(async (sp, ct) => {
        isExecuted = true;
    });

    await Task.Delay(10000);
    Assert.IsTrue(isExecuted);

    await service.StopAsync(CancellationToken.None);
}
[TestMethod]
公共异步任务验证\u托管的\u服务\u执行\u任务(){
IServiceCollection服务=新的ServiceCollection();
services.AddSingleton();
services.AddHostedService();
services.AddSingleton();
var serviceProvider=services.BuildServiceProvider();
var service=serviceProvider.GetService()作为QueuedHostedService;
var backgroundQueue=serviceProvider.GetService();
wait service.StartAsync(CancellationToken.None);
var isExecuted=false;
backgroundQueue.QueueBackgroundWorkItem(异步(sp、ct)=>{
isExecuted=真;
});
等待任务。延迟(10000);
Assert.IsTrue(已执行);
wait service.StopAsync(CancellationToken.None);
}

感谢您提供源代码的链接,这非常有帮助。我必须使用var service=serviceProvider.GetService();而不是QueuedHostedService来获取要填充的服务。@user1568891
QueuedHostedService
直接指的是他们在问题中使用的类型。@user1568891然后问题出在我的代码上。进一步检查后,您描述的行为是正确的,因为我发现该类没有直接注册到服务集合中。您还可以使用serviceProvider.GetServices().OfType().Single()获取新服务(如果您注册了多个HostedInstance,则尤其是yseful);关于“如何启动托管服务?”您应该使用来运行
IHostedService
。您还需要配置服务依赖项。请检查此项