.Net Core 6 – 关于在构造函数中运行异步任务,VSCode调试器不起作用。

huangapple go评论70阅读模式
英文:

.Net core 6 - About Async Task run in constructor, the VSCode Debugger is not work

问题

我有一个需要不断轮询设备信息的任务,所以我在构造函数中创建了这个任务。

public DeviceManager()
{
    Task.Run(Polling);
}

private Func<Task> Polling()
{
    return async () =>
        {
            while (true)
            {
                await GetInfo();
                await Task.Delay(60 * 1000);
            }
        }
}

通常我会运行 dotnet watch --no-hot-reload 来测试我的程序,但现在我想要调试它。

然而,当调试器运行时,它卡在这个 while 循环中。

请告诉我为什么我不能在这种情况下调试。

谢谢。

英文:

I have a Task that needs to continuously poll devices for information, so I created the Task in the constructor.

public DeviceManager()
{
    Task.Run(Polling);
}

private Func&lt;Task&gt; Polling()
{
    return async () =&gt;
        {
            while (true)
            {
                await GetInfo();
                await Task.Delay(60 * 1000);
            }
        }
}

I usually run dotnet watch --no-hot-reload to test my program, but now I want to debug it.

However, when the debugger is running, it hangs in this while loop.

Please let me know why I cannot debug in this situation.

Thanks.

答案1

得分: 1

这项任务从未存储在任何地方,因此在被安排执行之前,它可能已被垃圾回收。事实上,除非DeviceManager是一个单例,否则类本身可能会在生成它的请求完成后立即被垃圾回收。任务不是线程,它代表将来需要完成的一些工作。如果任务本身在被安排之前变成孤立状态,工作就会丢失。

在ASP.NET Core中创建后台服务是通过实现IHostedService接口来完成的。这在ASP.NET Core中使用托管服务进行后台任务中有描述。该文章展示了定期服务(轮询服务)和排队作业服务的示例。

定时后台服务非常简单,使用定时器定期调用其DoWork方法:

public class TimedHostedService : IHostedService, IDisposable
{
    private int executionCount = 0;
    private readonly ILogger&lt;TimedHostedService&gt; _logger;
    private Timer? _timer = null;

    public TimedHostedService(ILogger&lt;TimedHostedService&gt; logger)
    {
        _logger = logger;
    }

    private void DoWork(object? state)
    {
        var count = Interlocked.Increment(ref executionCount);

        _logger.LogInformation(
            &quot;Timed Hosted Service is working. Count: {Count}&quot;, count);
    }

    public Task StartAsync(CancellationToken stoppingToken)
    {
        _logger.LogInformation(&quot;Timed Hosted Service running.&quot;);

        _timer = new Timer(DoWork, null, TimeSpan.Zero,
            TimeSpan.FromSeconds(5));

        return Task.CompletedTask;
    }

    public Task StopAsync(CancellationToken stoppingToken)
    {
        _logger.LogInformation(&quot;Timed Hosted Service is stopping.&quot;);

        _timer?.Change(Timeout.Infinite, 0);

        return Task.CompletedTask;
    }

    public void Dispose()
    {
        _timer?.Dispose();
    }
}

StartAsyncStopAsync方法由ASP.NET Core主机调用以启动和停止服务。在这种情况下,它们只需要启动和停止计时器。

英文:

The task is never stored anywhere so it's probably garbage-collected before it ever has a chance to get scheduled for execution. In fact, unless DeviceManager is a Singleton, the class itself may get garbage-collected as soon as the request that spawned it completes. A Task isn't a thread, it represents some work that needs to complete in the future. If the task itself gets orphaned before it gets scheduled, the work is lost.

Creating background services in ASP.NET Core is done by implementing the IHostedService interface. This is described in Background tasks with hosted services in ASP.NET Core. That article shows both a poll service and a queued job service example.

The timed background service is pretty simple and uses a timer to call its DoWork method periodically:

public class TimedHostedService : IHostedService, IDisposable
{
    private int executionCount = 0;
    private readonly ILogger&lt;TimedHostedService&gt; _logger;
    private Timer? _timer = null;

    public TimedHostedService(ILogger&lt;TimedHostedService&gt; logger)
    {
        _logger = logger;
    }

    private void DoWork(object? state)
    {
        var count = Interlocked.Increment(ref executionCount);

        _logger.LogInformation(
            &quot;Timed Hosted Service is working. Count: {Count}&quot;, count);
    }

    public Task StartAsync(CancellationToken stoppingToken)
    {
        _logger.LogInformation(&quot;Timed Hosted Service running.&quot;);

        _timer = new Timer(DoWork, null, TimeSpan.Zero,
            TimeSpan.FromSeconds(5));

        return Task.CompletedTask;
    }

    public Task StopAsync(CancellationToken stoppingToken)
    {
        _logger.LogInformation(&quot;Timed Hosted Service is stopping.&quot;);

        _timer?.Change(Timeout.Infinite, 0);

        return Task.CompletedTask;
    }

    public void Dispose()
    {
        _timer?.Dispose();
    }
}

The StartAsync and StopAsync are called by the ASP.NET Core host to start and stop the service. In this case all they have to do is start and stop the timer.

huangapple
  • 本文由 发表于 2023年6月13日 14:39:11
  • 转载请务必保留本文链接:https://go.coder-hub.com/76462240.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定