Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/29.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 我在编写excel时遇到问题,无法停止执行_C#_Excel_Winforms - Fatal编程技术网

C# 我在编写excel时遇到问题,无法停止执行

C# 我在编写excel时遇到问题,无法停止执行,c#,excel,winforms,C#,Excel,Winforms,我这里有一个情况,我有一个程序,它的出口是一个excel文件,这是可以的,但有时我有一个大的excel文件要写,在某些情况下,我需要停止该程序,并停止该进程到另一个小时再做一次。但是,一旦我开始编写流程,我只能在停止使用VisualStudio时停止,重要的是要知道我使用的是表单应用程序,我尝试创建一个按钮,该按钮在它不运行流程时工作 进程运行时,似乎无法访问我的表单 有人能帮我解决这个问题吗?当您创建Excel应用程序时,您可以有效地创建一个新的进程Excel.EXE。您可以在“流程”选项卡上

我这里有一个情况,我有一个程序,它的出口是一个excel文件,这是可以的,但有时我有一个大的excel文件要写,在某些情况下,我需要停止该程序,并停止该进程到另一个小时再做一次。但是,一旦我开始编写流程,我只能在停止使用VisualStudio时停止,重要的是要知道我使用的是表单应用程序,我尝试创建一个按钮,该按钮在它不运行流程时工作

进程运行时,似乎无法访问我的表单


有人能帮我解决这个问题吗?

当您创建Excel应用程序时,您可以有效地创建一个新的进程Excel.EXE。您可以在“流程”选项卡上的“任务管理器”中找到它(在“应用程序”部分)。您只能通过终止Excel进程来停止操作-没有其他方法

为了释放UI线程,您应该在另一个线程上运行Excel操作。这是一个完美的候选人。由于Excel是非托管代码,因此需要释放对其对象的所有引用。这意味着必须释放代码中使用的每个属性和对象。但是……这还不够。问题是EXCEL.EXE进程可能仍在进程列表中—您可以在后台进程部分看到它。在某些情况下,这个过程可能会消失

总结一下我所说的,以下是您需要的基本框架:

1) 创建使用Excel的过程,将其包装在任务中并运行

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();
            }
        }
    }
}

正如您所说,流程运行时表单没有响应。当您从按钮clickhandler调用长时间运行的方法时,它将被此方法阻止。对于长时间运行的任务,您可以使用@H.G.Sandhagen Backgroundworker。OP应该使用任务。如果您展示一些用于编写Excel文件的代码会更好。我怀疑它需要很长时间才能完成的原因是,您要单独写入每个单元格,而不是写入数据块。可能仍然需要在辅助线程上执行该工作,但是可以将代码构造为检查取消请求并优雅地退出。