我在这里有一种情况,我有一个程序,出口是一个excel文件,可以,但是有时我要编写一个很大的Excel文件,在某些情况下,我需要停止该程序并终止该进程,再过一个小时再做一次。但是一旦开始编写过程,就只能在停止使用Visual Studio时停止,重要的是要知道我正在使用表单应用程序,我试图创建一个在不运行过程时可以工作的Button。>
进程运行时好像无法访问我的表单。
有人可以帮助我解决这种情况吗?
答案 0 :(得分:3)
创建Excel应用程序时,可以有效地创建一个新进程EXCEL.EXE。您可以在“进程”选项卡上的“任务管理器”(在“应用程序”部分中)中找到它。您只能通过终止Excel进程来停止操作-别无选择。
为了释放UI线程,应在另一个线程上运行Excel操作。 Task是完美的选择。由于Excel是非托管代码,因此您需要发布全部对其对象的引用。这意味着必须释放代码中使用的每个属性,每个对象。但是...这还不够。事实是EXCEL.EXE进程可能仍在进程列表中-您可以在背景进程部分中看到它。在某些情况下,该过程可能会消失。
总结一下我所说的内容,这是您需要的基本骨架:
1)创建适用于Excel的过程,将其包装在Task中并运行。
2)创建单独的过程,该过程可以由另一个按钮调用以停止 Excel过程。此过程还可以处理成功退出的情况。
using System.Runtime.InteropServices;
using Excel = Microsoft.Office.Interop.Excel;
namespace WinForms
{
public partial class Form1 : Form
{
// Hold reference to Excel
private Process xlProc = null;
private void OnRun(object sender, EventArgs e)
{
Task.Run(() =>
{
// Create new instance of EXCEL.EXE
var xlApp = new Excel.Application { Visible = true };
// Get Excel proccess in order to kill it
var handle = new IntPtr(xlApp.Hwnd);
xlProc = Process.GetProcesses().Where(p => p.MainWindowHandle == handle).First();
// Create new workbook
var xlBook = xlApp.Workbooks.Add();
var xlSheet = xlBook.Sheets[1] as Excel.Worksheet;
// Do some operation
xlSheet.Cells[1].Value = "Hello from .NET!";
// Quit
xlBook.Close(SaveChanges: false);
xlApp.Quit();
Marshal.ReleaseComObject(xlApp);
Marshal.ReleaseComObject(xlBook);
Marshal.ReleaseComObject(xlSheet);
GC.Collect();
GC.WaitForFullGCComplete();
KillExcel();
});
}
// Kill Excel process if it still exists
private void KillExcel()
{
if (!xlProc.HasExited)
{
xlProc.Kill();
}
}
}
}