在我的MainWindow
我有一个按钮,可用于打开Process
(本机OpenProcess
调用)并对其内存执行一些检查,但调用的方法Click
是异步的:
<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.
}
现在,让我们看看ViewModel
代码部分......
// 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;
}
现在……问题来了。当用户关闭应用程序时,如果Process
打开了 a,我必须正确关闭它的句柄。所以在我的MainWindow
我有以下代码:
protected override void OnClosing(CancelEventArgs e)
{
m_ViewModel.Detach();
base.OnClosing(e);
}
在我的ViewModel
我有以下代码:
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;
}
}
该Attach()
方法可能需要很长时间,有时超过 2 分钟。我需要找到以下问题的解决方案:
- 如果用户在
Attach()
方法运行时关闭应用程序并且之前memoryProcess
将其保存到私有变量,Process
则不会关闭句柄。 - 如果我在方法开始时将 MemoryProcess 实例保存到私有变量中,那么如果在方法处理其 foreach 循环时关闭应用程序,
Attach()
用户就有可能获得 a 。NullReferenceException
Attach()
- 我绝对不想让用户
Attach()
在让他关闭应用程序之前等待方法完成。那太糟了。
我怎样才能做到这一点?