如何在单独的线程上运行backgroundservices?

时间:2020-08-17 11:47:39

标签: c# .net asp.net-core .net-core backgroundworker

我意识到后台服务会阻塞主线程,并突然在主线程中造成延迟。我找不到有关如何使后台服务不产生延迟并阻塞主线程的有用资源。有什么建议吗?

public Task StartAsync(CancellationToken cancellationToken)
{
    _timer = new Timer(DoWork, null, 0, 10000);
    Initialize().GetAwaiter();

    return Task.CompletedTask;
}

private async void DoWork(object state)
{
    try
    {
        //some logic
        await testService.DoWorkAsync();
    }
    catch (Exception ex)
    {
        Log.Error(ex, "TestBackgroundService DoWork throws ");
    }
}


private async Task Initialize()
{
    while (true)
    {
        try
        {
            if (IsEnabled)
            {
                //some logic
                await testService.PrintAsync();
                IsEnabled = false;
            }
            else
            {
                //some logic
                await testService.CloseAsync();
                if (condition)
                {
                    IsEnabled = true;
                }
            }
            await Task.Delay(1000);
        }
        catch (Exception ex)
        {
            Log.Error($"ExecuteAsync throws {ex.ToString()}");
        }
    }
}

2 个答案:

答案 0 :(得分:1)

您必须以正确的方式使用它,我认为您想要的是范围内的后台任务:

https://docs.microsoft.com/en-us/aspnet/core/fundamentals/host/hosted-services?view=aspnetcore-3.1&tabs=visual-studio#consuming-a-scoped-service-in-a-background-task

这里有ExecuteAsync方法,您可以像这样使用它:

protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
    
    while (!stoppingToken.IsCancellationRequested)
    {
        //your code

        await DoWork(stoppingToken);
        Task.Delay(1000);
    }
}

答案 1 :(得分:0)

如果可能,您可以为后台作业创建一个控制器。

从您的代码中,您可以简单地使用HttpClient方法调用控制器操作。

private async Task ExecuteJobAsync(string jobName)
{
    // background job
    string uri = $"http://localhost:21454/api/jobs/{jobName}";

    using (HttpClient client = new HttpClient())
    {
        using (HttpContent content = new StringContent(string.Empty, Encoding.UTF8, "application/json"))
        {
            using (HttpResponseMessage response = await httpClient.PostAsync(uri, content).ConfigureAwait(false))
            {

            }
        }
    }
}

调用后台作业:

private async Task Initialize()
{
    while (true)
    {
        try
        {
            if (IsEnabled)
            {
                await ExecuteJobAsync("print");
                IsEnabled=false;
            }
            else
            {
                //some logic
                await ExecuteJobAsync("close");
                
                if(condition){
                    IsEnabled=true;
                }
            }
            
            await Task.Delay(1000);
        }
        catch (Exception ex)
        {
            Log.Error($"ExecuteAsync throws {ex.ToString()}");
        }
    }
}

作业控制器:

[Route("api/jobs")]
public class JobsController : Controller
{
    [HttpPost("print")]
    public void PrintAction()
    {
        // code
    }

    [HttpPost("close")]
    public void CloseAction()
    {
        // code
    }
}