2017-10-03 10 views
0


バックグラウンドワーカーとフォームに問題があります。
私は、ワーカーイベントRunWorkerCompletedでme.closeを呼び出そうとしていますが、myform.Designer.vbファイルのオーバーライドされた "Dispose" SubでStackOverflow例外が発生します。
「新しい」コンストラクタが必要なためにオーバーロードされる前に少し時間がかかりましたが、今はいつもStackOverflow例外が発生しますが、理由はわかりません。 デザイナーファイルは変更していませんが、前のコードを使用しても失敗しません。 一時的な解決策としてスタックサイズを増やすことはできますか? これは競合状態の結果ですか? 私はまた、バックグラウンドプロセスの優先度を上げ、UIを低くしてみました。System.ComponentModel.BackgroundWorker.RunWorkerCompletedからWinFormを閉じるときにvb.netでSystem.StackOverflowExceptionが発生する

次のように私のフォームのコードは次のとおりです。

Public Class frmProgreso 

Private elImpresionCancelada As Boolean 
Private WithEvents miWorker As System.ComponentModel.BackgroundWorker 
Private miListaReports As Report.EnumNombreReport() 
Private miListaReportsStr As String(,) 
Private miInforme_ruta As String 
Private miEmpresa As String 
Private miAño As Integer 
Private miMes As Integer 
Private oReport As Report 
Private lasCategorias As String() 
Private got_closing_order As Boolean = False 

Public Sub New(ByVal ListaReports As Report.EnumNombreReport(), ByVal Empresa As String, ByVal Año As Integer, ByVal Mes As Integer, ByVal OpcionMenu As String, ByVal Categorias As String()) 

    ' Llamada necesaria para el diseñador. 
    InitializeComponent() 

    ' Agregue cualquier inicialización después de la llamada a InitializeComponent(). 
    miEmpresa = Empresa 
    miAño = Año 
    miMes = Mes 
    lasCategorias = Categorias 
    miListaReports = ListaReports 
    ReiniciarInformes(0) 
    ReiniciarCeldas(0) 
    lblOpcionMenu.Text = OpcionMenu 

End Sub 
Public Sub New(ByVal informes As String(,), ByVal Empresa As String, ByVal Año As Integer, ByVal Mes As Integer, ByVal OpcionMenu As String, ByVal Categorias As String()) 

    ' Esta llamada es exigida por el diseñador. 
    InitializeComponent() 

    ' Agregue cualquier inicialización después de la llamada a InitializeComponent(). 
    miEmpresa = Empresa 
    miAño = Año 
    miMes = Mes 
    lasCategorias = Categorias 
    miListaReportsStr = informes 
    ReiniciarInformes(0) 
    ReiniciarCeldas(0) 
    lblOpcionMenu.Text = OpcionMenu 
End Sub 
Public Sub New(ByVal ruta_completa_informe As String, ByVal Empresa As String, ByVal Año As Integer, ByVal Mes As Integer, ByVal OpcionMenu As String, ByVal Categorias As String()) 

    ' Esta llamada es exigida por el diseñador. 
    InitializeComponent() 

    ' Agregue cualquier inicialización después de la llamada a InitializeComponent(). 
    miEmpresa = Empresa 
    miAño = Año 
    miMes = Mes 
    lasCategorias = Categorias 
    miInforme_ruta = ruta_completa_informe 
    ReiniciarInformes(0) 
    ReiniciarCeldas(0) 
    lblOpcionMenu.Text = OpcionMenu 
End Sub 

Public ReadOnly Property ProcesoCancelado() As Boolean 
    Get 
     Return elImpresionCancelada 
    End Get 
End Property 

Public Sub ImprimirDesdeCatalogo(Optional ByVal informes As String(,) = Nothing) 
    If Not IsNothing(informes) Then 
     miListaReportsStr = informes 
    End If 
    Me.Show() 
    LanzarImpresion() 
End Sub 

Public Sub ReiniciarCeldas(ByVal NumeroCeldas As Integer) 
    pbCeldas.Minimum = 0 
    pbCeldas.Maximum = NumeroCeldas 
    pbCeldas.Value = pbCeldas.Minimum 
    pbCeldas.Step = 1 
    lblCeldas.Text = String.Empty 
End Sub 

Public Sub ReiniciarInformes(ByVal NumeroInformes As Integer) 
    pbInformes.Minimum = 0 
    pbInformes.Maximum = NumeroInformes * 3 'Para cada informe, se realizan tres pasos: carga de plantilla en array, procesamiento de celdas y carga de array en plantilla 
    pbInformes.Step = 1 
    pbInformes.Value = pbInformes.Minimum 
    lblInforme.Text = String.Empty 
End Sub 

'Private Sub frmProgreso_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing 
' If miWorker.IsBusy() Then 
'  got_closing_order = True 
'  miWorker.CancelAsync() 
'  e.Cancel = True 
'  Me.Enabled = False 
'  Return 
' End If 
' MyBase.OnFormClosing(e) 
'End Sub 

Private Sub frmProgreso_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load 
    Me.WindowState = FormWindowState.Maximized 
    CentrarObjeto(gbPrincipal) 
End Sub 

Private Sub miWorker_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles miWorker.DoWork 
    System.Diagnostics.Process.GetCurrentProcess().PriorityClass = System.Diagnostics.ProcessPriorityClass.RealTime 
    If Not IsNothing(miListaReportsStr) Then 
     'Proceso nuevo. 
     miWorker.ReportProgress((UBound(miListaReportsStr, 1)) * 3, "INICIAR INFORMES") 'Para cada informe, se realizan tres pasos: carga de plantilla en array, procesamiento de celdas y carga de array en plantilla 
     For i As Integer = 0 To UBound(miListaReportsStr, 1) - 1 
      If miWorker.CancellationPending Then 
       Exit For 
      End If 
      'miWorker.ReportProgress(1, miListaReports.ElementAt(i).ToString) 
      oReport = New Report(miListaReportsStr(0, i), miEmpresa, miAño, miMes, miWorker, cRutaBase_InformesXLSGenerados, lasCategorias, miListaReportsStr(1, i)) 
      oReport.Imprimir(txtCeldaValidacion.Text.Trim) 
     Next 
    ElseIf miInforme_ruta <> "" Then 
     'proceso nuevo fichero individual 
     miWorker.ReportProgress(3, "INICIAR INFORMES") 'Para cada informe, se realizan tres pasos: carga de plantilla en array, procesamiento de celdas y carga de array en plantilla 
     'miWorker.ReportProgress(1, miListaReports.ElementAt(i).ToString) 
     oReport = New Report(miInforme_ruta, miEmpresa, miAño, miMes, miWorker, cRutaBase_InformesXLSGenerados, lasCategorias) 
     oReport.Imprimir(txtCeldaValidacion.Text.Trim) 

    Else 
     'Proceso Antiguo 
     miWorker.ReportProgress(miListaReports.Length * 3, "INICIAR INFORMES") 'Para cada informe, se realizan tres pasos: carga de plantilla en array, procesamiento de celdas y carga de array en plantilla 
     For i As Integer = 0 To miListaReports.Length - 1 
      If miWorker.CancellationPending Then 
       Exit For 
      End If 
      'miWorker.ReportProgress(1, miListaReports.ElementAt(i).ToString) 
      oReport = New Report(miListaReports.ElementAt(i), miEmpresa, miAño, miMes, miWorker, cRutaBase_InformesXLSGenerados, lasCategorias) 
      oReport.Imprimir(txtCeldaValidacion.Text.Trim) 
     Next 
    End If 
End Sub 

Private Sub miWorker_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles miWorker.ProgressChanged 
    If e.UserState = "INICIAR CELDAS" Then 
     pbCeldas.Minimum = 0 
     pbCeldas.Maximum = e.ProgressPercentage 
     pbCeldas.Value = pbCeldas.Minimum 
     pbCeldas.Step = 1 
     lblCeldas.Text = String.Empty 

    ElseIf e.UserState = "INCREMENTAR CELDAS" Then 
     pbCeldas.Value = pbCeldas.Value + 1 
     lblCeldas.Text = "Calculando celda " & pbCeldas.Value & "/" & pbCeldas.Maximum 
     'If pbCeldas.Value = 9811 Then 
     ' MessageBox.Show("1") 
     'End If 

    ElseIf e.UserState = "LEER CELDAS PLANTILLA" Then 
     pbCeldas.Value = pbCeldas.Value + 1 
     lblCeldas.Text = "Leyendo plantilla celda " & pbCeldas.Value & "/" & pbCeldas.Maximum 

    ElseIf e.UserState = "VOLCAR CELDAS PLANTILLA" Then 
     pbCeldas.Value = pbCeldas.Value + 1 
     lblCeldas.Text = "Escribiendo en plantilla celda " & pbCeldas.Value & "/" & pbCeldas.Maximum 

    ElseIf e.UserState = "INICIAR INFORMES" Then 
     pbInformes.Minimum = 0 
     pbInformes.Maximum = e.ProgressPercentage 
     pbInformes.Value = pbInformes.Minimum 
     pbInformes.Step = 1 
     lblInforme.Text = String.Empty 

    Else 
     lblInforme.Text = "Imprimiendo... < " & e.UserState & " > (Fase " & (pbInformes.Value Mod 3) + 1 & "/3)" ' 
     pbInformes.Value = pbInformes.Value + e.ProgressPercentage 
    End If 
End Sub 

Private Sub frmImportarInformesExcel_Paint(sender As Object, e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint 
    CentrarObjeto(gbPrincipal) 
End Sub 

Private Sub butCancelarImpresion_Click(sender As System.Object, e As System.EventArgs) Handles butCancelarImpresion.Click 
    If MessageBox.Show("¿Estás seguro de que deseas cancelar la impresión?", "Cancelar impresión", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) = Windows.Forms.DialogResult.Yes Then 
     elImpresionCancelada = True 
     If oReport IsNot Nothing Then 
      oReport.CancelarImpresion = True 
     End If 
     If miWorker IsNot Nothing Then 
      miWorker.CancelAsync() 
     End If 
     'Me.Close() 
     Me.Hide() 
    End If 
End Sub 

Private Sub LanzarImpresion() 
    System.Diagnostics.Process.GetCurrentProcess().PriorityClass = System.Diagnostics.Processpriorityclass.BelowNormal 
    butComenzar.Enabled = False 
    txtCeldaValidacion.Enabled = False 
    lblInforme.Visible = True 
    lblCeldas.Visible = True 
    pbCeldas.Visible = True 
    pbInformes.Visible = True 
    lblOpcionMenu.Visible = False 
    miWorker = New System.ComponentModel.BackgroundWorker() 
    miWorker.WorkerReportsProgress = True 
    miWorker.WorkerSupportsCancellation = True 
    miWorker.RunWorkerAsync() 
End Sub 

Private Sub butComenzar_Click(sender As System.Object, e As System.EventArgs) Handles butComenzar.Click 
    LanzarImpresion() 
End Sub 

Private Sub miWorker_RunWorkerCompleted(sender As Object, e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles miWorker.RunWorkerCompleted 
    ' a veces no se puede cerrar al usar el debugger... parece un error por utilizar hilos. ç 
    miWorker.CancelAsync() 
    miWorker.Dispose() 
    miWorker = Nothing 
    System.Diagnostics.Process.GetCurrentProcess().PriorityClass = System.Diagnostics.ProcessPriorityClass.Normal 
    Me.Dispose(False) 
End Sub 

Private Sub txtCeldaValidacion_LostFocus(sender As Object, e As EventArgs) Handles txtCeldaValidacion.LostFocus 
    txtCeldaValidacion.Text = Replace(Replace(Replace(txtCeldaValidacion.Text, " ", ""), ":", ""), "$", "") 
End Sub 

End Class 

編集1: 私は、コールスタックを見しようとしてきたと、はい、スタックオーバーフローがfrmprogreso上のDisposeメソッドのであり.designer.vbは何度も呼ばれています。 Effective stack overflow
しかし、私が見ることができるように、ユーザコード側からそれは一度だけ呼ばれています
...
Only one call from user code side

+0

Dispose()メソッドにブレークポイントを設定します。 2度目のヒットになると、コールスタックデバッガウィンドウの内容に興味を持っているはずです。あなたがそれを理解できなければ、その内容を投稿してください。 –

+0

何らかの理由で自動生成コードを変更しました。 'Me.Dispose'は、' MyBase.Dispose'だった致命的な間違いです。これがどのように起こったのか推測するのは難しいでしょう。 –

答えて

0

私の障害は、何らかの理由で(多分、私自身の障害)についてmyform.Designer.vb
にありました次のような方法だった処分:ハンスアンパッサンへ

Protected Overrides Sub Dispose(ByVal disposing As Boolean) 
    Try 
     If disposing AndAlso components IsNot Nothing Then 
      components.Dispose() 
     End If 
    Finally 
     Me.Dispose(disposing) 
    End Try 
End Sub 

多くのおかげで、大きな障害がある「Me.Dispose(処分)」、それは自分自身に呼び出していることを指しているため。それは間違いなくMyBase.Dispose(disposing)にする必要があります。

関連する問題