Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/14.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
.net 诊断;超过配额;Win32异常_.net_Wpf_Performance_Winapi_Win32exception - Fatal编程技术网

.net 诊断;超过配额;Win32异常

.net 诊断;超过配额;Win32异常,.net,wpf,performance,winapi,win32exception,.net,Wpf,Performance,Winapi,Win32exception,大多数时候,作为一名.Net开发人员,我们可以自由地在高层次的抽象世界中游手好闲,但有时现实会在你的隐私部分踢你一脚,告诉你找到一个真正理解的人 我刚刚有过这样的经历。我认为将角落数据列为项目列表就足够了,这样您就可以了解我们这里的内容: Win2008服务器 64位环境 多个客户端同时使用的WPF应用程序 应用程序是一个启动器,它使用Process.Start()打开其他应用程序 偶尔我们会遇到下面列出的例外情况 编辑#1 经过一些检查,这里有更多的细节: 发射是一个两步过程,发射器发射

大多数时候,作为一名.Net开发人员,我们可以自由地在高层次的抽象世界中游手好闲,但有时现实会在你的隐私部分踢你一脚,告诉你找到一个真正理解的人

我刚刚有过这样的经历。我认为将角落数据列为项目列表就足够了,这样您就可以了解我们这里的内容:

  • Win2008服务器
  • 64位环境
  • 多个客户端同时使用的WPF应用程序
  • 应用程序是一个启动器,它使用Process.Start()打开其他应用程序
  • 偶尔我们会遇到下面列出的例外情况
编辑#1 经过一些检查,这里有更多的细节:

  • 发射是一个两步过程,发射器发射一个中间过程 使用Process.WaitForExit()的窗口

  • 在中间窗口中,可以以相同的方式启动其他进程(Process.WaitForExit)

  • 只有中间窗口打开,没有用户交互,启动程序进程的句柄数量会随着时间的推移而增加。我们在这里看到的最大增加是400-->6000个句柄

编辑中添加的事实确实让我想知道框架中的某个地方是否存在句柄泄漏。我正在尝试隔离问题,并检查是否可以从头开始复制它。同时,任何暗示、想法、支持甚至巧克力都会被欣然接受

EDIT#2:为了使进程响应
PostMessage()
,我们删除了
线程。WaitForExit
。相反,我们为流程的Exited事件添加了一个处理程序,并将启动器发送到一个循环中,如下所示:

       while (foo == true)
        {
            System.Threading.Thread.Sleep(1000);
        }
退出的处理程序将
foo
设置为false,并且不执行其他操作。 尽管如此,手柄的数量还是在增加(半小时内从400个增加到800个)

编辑#3 终于有有趣的事情发生了

       while (foo == true)
        {
            System.Threading.Thread.Sleep(1000);
            GC.Collect();
        }

这使它保持了它应该是的样子,几个把手,所有漂亮的。现在这让我想知道这里出了什么问题……我将再次与负责的开发人员交谈,以检查启动器的其他功能。到目前为止,我听说它使用读取一些配置值,这不是一个
IDisposable
-这使得在这里很难产生任何泄漏…

错误告诉您,在向窗口发布消息时,窗口的消息队列已达到其最大容量。这意味着拥有该窗口的线程处理消息的速度不够快(如果有的话)。

我知道这个问题已经提出六年了,但我们刚刚遇到了同样的问题,我用它来启发自己。但我不喜欢的是睡线和圈的想法

相反,我创建了一个WPF窗口。使它透明,一个像素高和宽,并添加了公共属性类型的过程

然后,我没有调用.WaitForExit,而是编写了一个共享子组件(对不起,我使用的是VB.NET术语),它执行以下操作

Public Shared Sub DoWaitForProcessToExit(ByVal poProc As Process, ByVal oOwner As Window)
    Dim oWFE As WaitForProcessToExit
    poProc.EnableRaisingEvents = True
    oWFE = New WaitForProcessToExit
    oWFE.oProc = poProc
    If Not oOwner Is Nothing Then
        oWFE.Owner = oOwner
    End If
    oWFE.ShowDialog()
    oWFE = Nothing
End Sub
以防在激活此对话框时发生错误且进程已退出:

Private Sub WaitForProcessToExit_Activated(sender As Object, e As EventArgs) Handles Me.Activated

    Try
        If oProc.HasExited Then
            Try
                RemoveHandler oProc.Exited, AddressOf oProc_Exited
            Catch ex As Exception

            End Try
            'whatever happened .... it seems to have gone too quick for this to invoke the _Exited event
            Me.Close()
        End If
    Catch
        Try
            Try
                RemoveHandler oProc.Exited, AddressOf oProc_Exited
            Catch ex As Exception

            End Try
            Me.Close()
        Catch

        End Try
    End Try
End Sub
现在,我只需在加载对话框时执行此操作:

Private Sub WaitForProcessToExit_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded

    AddHandler oProc.Exited, AddressOf oProc_Exited

End Sub
然后只响应退出的事件。没有睡眠,没有循环

Private Sub oProc_Exited(sender As Object, e As EventArgs)

    'This event is raised by the exiting process, which is in a different thread, so, invoke my own
    'close method from my own Dispatcher
    Windows.Application.Current.Dispatcher.Invoke(Sub() CloseMe(), Windows.Threading.DispatcherPriority.Render)

End Sub

Private Sub CloseMe()

    Me.Close()

End Sub

嗯。这可能会返回到Thread.WaitForExit(),这会使线程在子线程退出之前没有响应……谢谢,我将尝试使用基于事件的方式处理进程退出,并在这里发回反馈。请注意,这实际上只是替换了.WaitForExit调用。调用代码应该已经负责关闭和处理进程对象,并在必要时进行垃圾收集。
Private Sub oProc_Exited(sender As Object, e As EventArgs)

    'This event is raised by the exiting process, which is in a different thread, so, invoke my own
    'close method from my own Dispatcher
    Windows.Application.Current.Dispatcher.Invoke(Sub() CloseMe(), Windows.Threading.DispatcherPriority.Render)

End Sub

Private Sub CloseMe()

    Me.Close()

End Sub