我遇到了后台工作人员和表格。
我试图在工作事件RunWorkerCompleted上调用me.close,但它在myform.Designer.vb文件的重写“Dispose”Sub上拖出了StackOverflow异常。
在我因为需要而重载“New”构造函数之前,它工作了一段时间,现在我总是得到一个StackOverflow异常,但我不知道为什么。
我没有更改设计器文件,但如果我使用以前的代码,它不会失败。
我可以将堆栈大小增加为临时解决方案吗?
这是竞争条件的结果吗?
我还尝试增加后台进程优先级并降低用户界面,没有运气。
我的表单代码如下:
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.designer.vb上的dispose方法被多次调用。
Effective stack overflow
但是从用户代码方面来看,它只被调用一次,因为我可以看到...
Only one call from user code side
答案 0 :(得分: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
非常感谢Hans Passant指出&#34; Me.Dispose(处理)&#34;这是一个大错,它是在呼唤自己。它应该绝对是MyBase.Dispose(disposing)