0

I have the following code that is supposed to run in a background worker when I hit the red X button to close the form:

Private Sub Form1_FormClosed(ByVal sender As System.Object, ByVal e As System.Windows.Forms.FormClosedEventArgs) Handles MyBase.FormClosed
    picLoading.Visible = True
    tblMain.Visible = False
    bwQuitNoSave.RunWorkerAsync()

End Sub

Private Sub bwQuitNoSave_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles bwQuitNoSave.DoWork
    'If at least one sheet has been opened, close the workbook
    If FirstLoad = 2 Then
        worksheet.Cells(1, 31).Value = ""
        workbook.Save()
        workbook.Close(False)
    End If
End Sub

Private Sub bwQuitNoSave_RunWorkerCompleted(sender As Object, e As RunWorkerCompletedEventArgs) Handles bwQuitNoSave.RunWorkerCompleted
    'Exit the application
    APP.Quit()
End Sub



So what's supposed to happen is that the application checks to see if an integer = 2, and if it is, it saves the workbook, closes it, and then quits the application. However when I run this code, even when the application is closed, the excel process stays open.

In a previous iteration of my application, I was using this code which functioned correctly (e.g. closed out the excel process):

Private Sub Form1_FormClosed(ByVal sender As System.Object, ByVal e As System.Windows.Forms.FormClosedEventArgs) Handles MyBase.FormClosed

   picLoading.Visible = True
   tblMain.Visible = False

   'If at least one sheet has been opened, close the workbook
   If FirstLoad = 2 Then
       worksheet.Cells(1, 31).Value = ""
       workbook.Save()
       workbook.Close(False)
   End If
   'Exit the application
       APP.Quit()

End Sub

Does anyone see what I'm missing?


I've also tried this, and the process still remains open:

 Private Sub bwQuitNoSave_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles bwQuitNoSave.DoWork
        'If at least one sheet has been opened, close the workbook
        If FirstLoad = 2 Then
            worksheet.Cells(1, 31).Value = ""
            workbook.Save()
            workbook.Close(False)
        End If
    Try
        workbook.Close(False)
        APP.Quit()
    Catch
        APP.Quit()
    End Try
    End Sub

    Private Sub bwQuitNoSave_RunWorkerCompleted(sender As Object, e As RunWorkerCompletedEventArgs) Handles bwQuitNoSave.RunWorkerCompleted
        'Exit the application
        releaseMemory(APP)
        releaseMemory(worksheet)
        releaseMemory(workbook)

    End Sub

    Private Sub releaseMemory(ByVal obj As Object)
        Try
            System.Runtime.InteropServices.Marshal.ReleaseComObject(obj)
            obj = Nothing
        Catch ex As Exception
            obj = Nothing
        Finally
            GC.Collect()
        End Try
    End Sub









Solved it after many, many tries:

Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles MyBase.FormClosing
    If e.CloseReason = CloseReason.UserClosing Then
        e.Cancel = True
        picLoading.Visible = True
        tblMain.Visible = False
        If FirstLoad = 2 Then
            worksheet.Cells(1, 31).Value = ""
            bwQuitNoSave.RunWorkerAsync()
        Else
            Quit()
        End If
    End If
End Sub
Public Sub Quit()
    APP.Quit()
    GC.Collect()
    GC.WaitForPendingFinalizers()
    GC.Collect()
    GC.WaitForPendingFinalizers()
    Application.Exit()
End Sub
Private Sub bwQuitNoSave_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles bwQuitNoSave.DoWork
    'If at least one sheet has been opened, close the workbook
    workbook.Save()
End Sub

Private Sub bwQuitNoSave_RunWorkerCompleted(sender As Object, e As RunWorkerCompletedEventArgs) Handles bwQuitNoSave.RunWorkerCompleted
    Quit()
End Sub




Turns out the key was to have the exit via the red X canceled and manually close out the application.

lolikols
  • 87
  • 1
  • 5
  • 24
  • 1
    Possible duplicate of [Excel application not quitting after calling quit](http://stackoverflow.com/questions/15697282/excel-application-not-quitting-after-calling-quit) This has been asked several times here before, that's one case... – Trevor Jan 16 '17 at 18:25
  • You could quit the app in the BGW also. Use the `Marshal.FinalReleaseComObject` method to dispose of the Excel obects. – OneFineDay Jan 16 '17 at 18:26
  • Hey guys, thank you for your replies. I've actually tried that, and the process remains open. I didn't include it in the code, because I thought it was faulty code, but I'll add it. – lolikols Jan 16 '17 at 18:34
  • Order is important when releasing COM objects; worksheet then workbook and finally the app. – Trevor Jan 16 '17 at 18:49
  • @Zaggler thanks, just tried it, but the process still remains open. I tried both worksheet, workbook, and app and app, workbook, worksheet. – lolikols Jan 16 '17 at 19:00
  • Make sure you close the workbook and then the app first. Then try releasing the COM objects. From what I see its only closed if it meets the if condition, you need to close it no matter what. – Trevor Jan 16 '17 at 19:08
  • I added a try statement like so: Try workbook.Close(False) APP.Quit() Catch APP.Quit() End Try Still no go. – lolikols Jan 16 '17 at 19:23
  • Edited original post to include Try. I'm a little confused why this worked prior to me adding a backgroundworker. – lolikols Jan 16 '17 at 19:35
  • Try putting your `FirstLoad` block in the `RunWorkerCompleted` event handler. Does that improve things? – InteXX Jan 16 '17 at 20:50
  • @InteXX Ah, that was a good idea, but sadly, no go still :( – lolikols Jan 16 '17 at 21:05
  • I see you got it. Have you considered using `Async/Await` instead? `BackgroundWorker` is old news anymore. – InteXX Jan 16 '17 at 21:45
  • @InteXX I disagree, older frameworks don't support the async/await directly without the help of Microsoft.Bcl.Async. So in many cases still it is useful, do you mind explaining why it's in your opinion ***old news***...? – Trevor Jan 17 '17 at 00:26
  • @Zaggler: I agree that it's still useful in edge cases, such as those you describe in which we can't use `Asycn/Await`, but the resulting extra verbosity and complexity makes the newer model the preferable one when possible. `BackgroundWorker` remains a good fallback tool. After all, it still works, right? But it's old news. – InteXX Jan 17 '17 at 00:41

0 Answers0