Tommaso Belluzzo
Tommaso Belluzzo

Reputation: 23685

About Async Tasks and Disposal

In my MainWindow I have a button that can be used to open a Process (native OpenProcess call) and perform some checks on it's memory, but the method called on Click is asynchronous:

<Button Content="Attach" Click="OnClickAttach"/>

private async void OnClickAttach(Object sender, RoutedEventArgs e)
{
    AttachmentResult result = await m_ViewModel.Attach();

    switch (result)
        // Different MessageBox depending on the result.
}

Now, let's see the ViewModel portion of code...

// MemoryProcess class is just a wrapper for Process' handle and memory regions.
private MemoryProcess m_MemoryProcess;

public async Task<AttachmentResult> Attach()
{
    AttachmentResult result = AttachmentResult.Success;
    MemoryProcess memoryProcess = NativeMethods.OpenProcess(m_SelectedBrowserInstance.Process);

    if (memoryProcess == null)
        result = AttachmentResult.FailProcessNotOpened;
    else
    {
        Boolean check1 = false;
        Boolean check2 = false;

        foreach (MemoryRegion region in memoryProcess)
        {
            // I perform checks on Process' memory regions and I eventually change the value of check1 or check2...
            await Task.Delay(1);
        }

        if (!check1 && !check2)
        {
            NativeMethods.CloseHandle(memoryProcess.Handle);
            result = AttachmentResult.FailProcessNotValid;
        }
        else
        {
            // I keep the Process opened for further use. I save it to a private variable.
            m_MemoryProcess = memoryProcess;
            m_MemoryProcess.Check1 = check1;
            m_MemoryProcess.Check2 = check2;
        }
    }

    return result;
}

Now... here comes the problem. When the user closes the application, if a Process is opened, I must properly close its handle. So in my MainWindow I have the following code:

protected override void OnClosing(CancelEventArgs e)
{
    m_ViewModel.Detach();
    base.OnClosing(e);
}

And in my ViewModel I have the following code:

public void Detach()
{
    if (m_MemoryProcess != null)
    {
        if (m_MemoryProcess.Check1)
            // Do something...

        if (m_MemoryProcess.Check2)
            // Do something...

        NativeMethods.CloseHandle(m_MemoryProcess.Handle);
        m_MemoryProcess = null;
    }
}

The Attach() method can take very long time, more than 2 minutes sometimes. I need to find a solution for the following issues:

How can I do this?

Upvotes: 1

Views: 537

Answers (1)

IMO, if you do not explicitly and specifically target to create separate detached/independent processes like, for example, through:

  • using PInvoke.CreateProcess
  • using

    (new System.Management.ManagementClass("Win32_ProcessStartup"))
    .Properties["CreateFlags"].Value = 8;
    
  • or maintaining child process alive upon app closing by launching them through separate shell scripts or other processes remaining to run after app closing;

  • creating a new thread in another independent process using CreateRemoteThread
  • etc.

or finding already run independently processes, you don't need to and probably should not "close" or dispose spawned by app processes. Windows (operting system) will close any unclosed spawned by app processes.

Also, I believe that it is impossible to execute any code in an application once it has started exiting or being closed.

PS (off-topic comment):
I do not even see that you close (really one should kill) or dispose your processes in your code...

Upvotes: 1

Related Questions