Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/374.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
Javascript instance.invokeMethod内存泄漏_Javascript_Visual Studio_Blazor - Fatal编程技术网

Javascript instance.invokeMethod内存泄漏

Javascript instance.invokeMethod内存泄漏,javascript,visual-studio,blazor,Javascript,Visual Studio,Blazor,我通过.invokeMethod打了很多回C#的电话,我的垃圾收集器似乎被卡住了。显然,我不太了解Javascript/Blazor互操作内存管理,所以希望你们中的一位能够提供帮助 我正在设置window.requestAnimationFrame以调用c#。JS如下所示: <script type="text/javascript"> window.anim = { start: function (instance) { cons

我通过.invokeMethod打了很多回C#的电话,我的垃圾收集器似乎被卡住了。显然,我不太了解Javascript/Blazor互操作内存管理,所以希望你们中的一位能够提供帮助

我正在设置window.requestAnimationFrame以调用c#。JS如下所示:

<script type="text/javascript">

    window.anim = {
        start: function (instance) {
            console.log('start');
            return window.requestAnimationFrame(function (timestamp) { anim.callback(instance); });
        },

        callback: function (instance) {
            instance.invokeMethod('IncrementCount');
            var callbackId = window.requestAnimationFrame(function (timestamp) { anim.callback(instance); });

        },

        stop: function (callbackId) {
            window.cancelAnimationFrame(callbackId);
        }
    };

</script>
@page "/counter"
@inject IJSRuntime JSRuntime;

<h1>Counter</h1>

<p>Current count: @currentCount</p>

<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>

@code {
    private int currentCount = 0;

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            var dotNetReference = DotNetObjectReference.Create(this);
            await JSRuntime.InvokeAsync<string>("window.anim.start", dotNetReference);
        }
    }

    [JSInvokable("IncrementCount")]
    public void IncrementCount()
    {
        currentCount++;

        StateHasChanged();
    }
}

window.anim={
开始:函数(实例){
console.log('start');
返回window.requestAnimationFrame(函数(时间戳){anim.callback(实例);});
},
回调:函数(实例){
invokeMethod('IncrementCount');
var callbackId=window.requestAnimationFrame(函数(时间戳){anim.callback(实例);});
},
停止:函数(回调ID){
window.cancelAnimationFrame(callbackId);
}
};
我的Razor页面如下所示:

<script type="text/javascript">

    window.anim = {
        start: function (instance) {
            console.log('start');
            return window.requestAnimationFrame(function (timestamp) { anim.callback(instance); });
        },

        callback: function (instance) {
            instance.invokeMethod('IncrementCount');
            var callbackId = window.requestAnimationFrame(function (timestamp) { anim.callback(instance); });

        },

        stop: function (callbackId) {
            window.cancelAnimationFrame(callbackId);
        }
    };

</script>
@page "/counter"
@inject IJSRuntime JSRuntime;

<h1>Counter</h1>

<p>Current count: @currentCount</p>

<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>

@code {
    private int currentCount = 0;

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            var dotNetReference = DotNetObjectReference.Create(this);
            await JSRuntime.InvokeAsync<string>("window.anim.start", dotNetReference);
        }
    }

    [JSInvokable("IncrementCount")]
    public void IncrementCount()
    {
        currentCount++;

        StateHasChanged();
    }
}
@page”/counter
@注入IJSRuntime JSRuntime;
柜台
当前计数:@currentCount

点击我 @代码{ 私有int currentCount=0; AfterRenderAsync(bool firstRender)上受保护的重写异步任务 { if(firstRender) { var dotNetReference=DotNetObjectReference.Create(此); 等待JSRuntime.InvokeAsync(“window.anim.start”,dotNetReference); } } [JSInvokable(“IncrementCount”)] 公共无效增量计数() { currentCount++; StateHasChanged(); } }
我的垃圾收集器很快就会出现“GC_MINOR:(托儿所满)”消息,我的System/JSArrayBufferData看起来很大。 从文档中,我可以推断出应该处理对象,但它们也应该在这样的实例中处理吗?(在哪里?!)

(更新:好的,所以System/JSArrayBufferData总是很大,即使在运行Blazor示例时也是如此。所以我想这本身并没有任何迹象……但这仍然对我没有帮助)

这是一个问题的原因是,当我尝试做任何有意义的事情时,GC通常会立即启动。这里的例子只是为了说明即使在最简单的情况下也会发生这种情况

谢谢


/托马斯

这可能不起作用,并被添加为对原始问题的评论的更完整的建议。我会鼓励OP评论这有多有效,也鼓励其他人纠正我的错误,以便我能了解更多

由于“IJSRuntime”填满了内存,其背后的思想是,运行时的生存期可能比它应该持续的时间长得多,而且由于Blazor是一个有状态的框架,因此状态也会随之产生

可以尝试使用
OwningComponentBase
将JS运行时的作用域强制到组件的生命周期、Blazor服务器中连接的生命周期或Blazor WASM中的单例。设置应该只需要几行代码。在Razor文件的顶部:

@继承OwningComponentBase
然后在@code块中:

@code{
//属性,而不是在此处注入
公共IJSRuntime运行时{get;set;}
//将运行时设置为作用域服务,因此它将发布并可用
//用于在拆下组件时进行垃圾收集
受保护的覆盖无效OnInitialized()
{
运行时=ScopedServices.GetRequiredService();
}
}
如果我的想法是正确的,这将有助于内存管理。我鼓励其他可能对这一主题更了解的人也评论或编辑这篇文章

以下是Blazor中关于作用域服务生命周期的说明


希望这有帮助,请回来报告

这可能不起作用,将作为对原始问题的评论的更完整建议添加。我会鼓励OP评论这有多有效,也鼓励其他人纠正我的错误,以便我能了解更多

由于“IJSRuntime”填满了内存,其背后的思想是,运行时的生存期可能比它应该持续的时间长得多,而且由于Blazor是一个有状态的框架,因此状态也会随之产生

可以尝试使用
OwningComponentBase
将JS运行时的作用域强制到组件的生命周期、Blazor服务器中连接的生命周期或Blazor WASM中的单例。设置应该只需要几行代码。在Razor文件的顶部:

@继承OwningComponentBase
然后在@code块中:

@code{
//属性,而不是在此处注入
公共IJSRuntime运行时{get;set;}
//将运行时设置为作用域服务,因此它将发布并可用
//用于在拆下组件时进行垃圾收集
受保护的覆盖无效OnInitialized()
{
运行时=ScopedServices.GetRequiredService();
}
}
如果我的想法是正确的,这将有助于内存管理。我鼓励其他可能对这一主题更了解的人也评论或编辑这篇文章

以下是Blazor中关于作用域服务生命周期的说明


希望这有帮助,请回来报告

所以,在进一步调查之后,我相当肯定我误解了Mono-GC消息的内存泄漏

看起来根本没有泄漏,但GC只是让您知道它正在清理。为这场白费力气的追逐道歉!:)

我仍然关心触发这篇文章()的项目中GC提供的信息量,但我将对此进行更多的研究


谢谢

所以,在进一步调查之后,我相当肯定我误解了Mono-GC消息的内存泄漏

看起来没有漏水