Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.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
Blazor html5画布和c#计时器上的GC#U小问题_C#_Asp.net Core_Canvas_Timer_Blazor - Fatal编程技术网

Blazor html5画布和c#计时器上的GC#U小问题

Blazor html5画布和c#计时器上的GC#U小问题,c#,asp.net-core,canvas,timer,blazor,C#,Asp.net Core,Canvas,Timer,Blazor,我想在htm5画布上实现圆形动画。我对blazor使用html5画布扩展。我做错了什么?在运行的blazor服务器上,在web assembly上,我在开发者工具中获得了GC_minor,我可以重现同样的问题: @的上述评论是正确的。您至少应该检查firstRender是否为true,并避免每次将draw()函数附加到新计时器 除此之外,您应该创建一个计时器,作为一个单独的字段。当组件被释放时,不要忘记释放定时器 最后,代码中还有另一个问题:您没有调用\u context.EndBatchAsy

我想在htm5画布上实现圆形动画。我对blazor使用html5画布扩展。我做错了什么?在运行的blazor服务器上,在web assembly上,我在开发者工具中获得了GC_minor,我可以重现同样的问题:

  • @的上述评论是正确的。您至少应该检查
    firstRender
    是否为true,并避免每次将
    draw()
    函数附加到新计时器
  • 除此之外,您应该创建一个
    计时器
    ,作为一个单独的字段。当组件被释放时,不要忘记释放
    定时器
  • 最后,代码中还有另一个问题:您没有调用
    \u context.EndBatchAsync()
    。因此,它不会绘制任何内容
  • 要解决上述问题,请按以下方式更改代码:

    private Canvas2DContext _context;
    
    protected BECanvasComponent _canvasReference;
    
    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        this._context = await this._canvasReference.CreateCanvas2DAsync();
    
        var centerX = _canvasReference.Width / 2;
        var centerY = _canvasReference.Height / 2;
        var radius = 80;
        var full = radius * 2;
        var amount = 0.0;
        var amountToIncrease = 0.1;
    
        var aTimer = new Timer(500);
    
        async void draw(Object source, ElapsedEventArgs e)
        {
            await this._context.BeginBatchAsync();
            await this._context.ArcAsync(centerX, centerY, radius, 0, amount * Math.PI, false);
            await this._context.SetFillStyleAsync("#13a8a4");
            await this._context.FillAsync();
            await this._context.SetLineWidthAsync(10);
            await this._context.SetStrokeStyleAsync("#000000");
            await this._context.StrokeAsync();
            amount += amountToIncrease;
            if (amount > full) amount = 0; // restart
    
            await InvokeAsync(() =>
            {
                StateHasChanged();
            });          
        }
    
        aTimer.Elapsed += draw;
        aTimer.AutoReset = true;
        aTimer.Enabled = true;
    }
    
    [Demo2]:


    顺便说一下,您不必通知此处的状态已更改(因为您没有更改组件状态):


    这可能与这样的事实有关:如果(firstRender){您的代码应该在这里,并且只执行一次}否则,只要执行OnAfterRenderAsync,代码就会执行(super:)。我想知道为什么圆圈里有这些线?@MariusJurjonas我编辑了我的答案,告诉你原因以及如何避免这些线。请检查:) ... @implements IDisposable @* A Timer is a resource that should be disposed *@ ... @code{ private Canvas2DContext _context; protected BECanvasComponent _canvasReference; private Timer _aTimer = new Timer(500); public void Dispose() { this._aTimer.Dispose(); } protected override async Task OnAfterRenderAsync(bool firstRender) { this._context = await this._canvasReference.CreateCanvas2DAsync(); var centerX = _canvasReference.Width / 2; var centerY = _canvasReference.Height / 2; var radius = 80; var full = radius * 2; var amount = 0.0; var amountToIncrease = 0.1; if(firstRender) { // you might decide to put the above `var amount = 0.0; ...` here too, it depends on your needs this._aTimer.Elapsed += draw; this._aTimer.AutoReset = true; this._aTimer.Enabled = true; } async void draw(Object source, ElapsedEventArgs e) { await this._context.BeginBatchAsync(); await this._context.ArcAsync(centerX, centerY, radius, 0, amount * Math.PI, false); await this._context.SetFillStyleAsync("#13a8a4"); await this._context.FillAsync(); await this._context.SetLineWidthAsync(10); await this._context.SetStrokeStyleAsync("#000000"); await this._context.StrokeAsync(); await this._context.EndBatchAsync(); // add this line ! amount += amountToIncrease; if (amount > full) amount = 0; // restart await InvokeAsync(() => { StateHasChanged(); }); } } } await this._context.BeginBatchAsync(); await this._context.BeginPathAsync(); // add this line await this._context.ArcAsync(centerX, centerY, radius, 0, amount * Math.PI, false); ...
    //await InvokeAsync(() => { StateHasChanged(); });