C# Excel COM互操作,编辑单元格时进程未完成
我正在尝试通过COM互操作使用Excel。它工作正常,但在C# Excel COM互操作,编辑单元格时进程未完成,c#,.net,excel,com,office-interop,C#,.net,Excel,Com,Office Interop,我正在尝试通过COM互操作使用Excel。它工作正常,但在DoStuff方法完成后,Excel进程仍然挂起(尽管在我的程序完成时它消失) 如果删除填充单元格的代码,则不会出现此问题 using System; using System.Reflection; using System.Runtime.InteropServices; using Excel = Microsoft.Office.Interop.Excel; namespace ConsoleApplication13 {
DoStuff
方法完成后,Excel进程仍然挂起(尽管在我的程序完成时它消失)
如果删除填充单元格的代码,则不会出现此问题
using System;
using System.Reflection;
using System.Runtime.InteropServices;
using Excel = Microsoft.Office.Interop.Excel;
namespace ConsoleApplication13
{
class Program
{
static void DoStuff()
{
string workbookPath = @"C:\....xlsx";
var excelApp = new Excel.Application();
excelApp.Visible = true;
var workbooks = excelApp.Workbooks;
var workbook = workbooks.Open(workbookPath,
0, false, 5, "", "", false, Excel.XlPlatform.xlWindows, "",
true, false, 0, true, false, false);
var workheets = workbook.Worksheets;
var mainWorksheet = (Excel.Worksheet) workheets.Item[1];
var cell = (Excel.Range)mainWorksheet.Cells[4, "U"];
cell.set_Value(Missing.Value, 99);
ReleaseObject(cell);
ReleaseObject(mainWorksheet);
ReleaseObject(workheets);
workbook.Close(false, Missing.Value, Missing.Value);
ReleaseObject(workbook);
ReleaseObject(workbooks);
excelApp.Quit();
ReleaseObject(excelApp);
}
private static void ReleaseObject(object obj)
{
if (obj != null && Marshal.IsComObject(obj))
{
Marshal.ReleaseComObject(obj);
}
}
static void Main(string[] args)
{
DoStuff();
Console.ReadKey();
}
}
}
我正试图存储对COM对象的所有引用,并按照这里的建议发布它,但它对单元格不起作用,我不明白为什么。我最终用GC方法做了类似的事情。看起来效果不错
using System;
using System.Reflection;
using Excel = Microsoft.Office.Interop.Excel;
namespace ConsoleApplication13
{
class ExcelWorker : IDisposable
{
private Excel.Application _excelApp;
private Excel.Workbook _workbook;
private Excel.Worksheet _mainWorksheet;
private readonly string _workbookPath;
public ExcelWorker(string workbookPath)
{
_workbookPath = workbookPath;
}
public void Start()
{
_excelApp = new Excel.Application();
_excelApp.Visible = true;
var workbooks = _excelApp.Workbooks;
_workbook = workbooks.Open(_workbookPath,
0, false, 5, "", "", false, Excel.XlPlatform.xlWindows, "",
true, false, 0, true, false, false);
var workheets = _workbook.Worksheets;
_mainWorksheet = (Excel.Worksheet) workheets.Item[1];
}
public void DoStuff()
{
var cell = (Excel.Range)_mainWorksheet.Cells[4, "U"];
cell.set_Value(Missing.Value, 99);
}
public void Stop()
{
if (_workbook != null)
{
_workbook.Close(false, Missing.Value, Missing.Value);
_workbook = null;
_mainWorksheet = null;
}
if (_excelApp != null)
{
_excelApp.Quit();
_excelApp = null;
}
GC.Collect();
GC.WaitForPendingFinalizers();
}
public void Dispose()
{
Stop();
}
}
class Program
{
static void Main(string[] args)
{
using (var excelWorker = new ExcelWorker(@"C:\.....xlsx"))
{
excelWorker.Start();
excelWorker.DoStuff();
excelWorker.DoStuff();
}
Console.ReadKey();
}
}
}
我最终用GC方法做了类似的事情。看起来效果不错
using System;
using System.Reflection;
using Excel = Microsoft.Office.Interop.Excel;
namespace ConsoleApplication13
{
class ExcelWorker : IDisposable
{
private Excel.Application _excelApp;
private Excel.Workbook _workbook;
private Excel.Worksheet _mainWorksheet;
private readonly string _workbookPath;
public ExcelWorker(string workbookPath)
{
_workbookPath = workbookPath;
}
public void Start()
{
_excelApp = new Excel.Application();
_excelApp.Visible = true;
var workbooks = _excelApp.Workbooks;
_workbook = workbooks.Open(_workbookPath,
0, false, 5, "", "", false, Excel.XlPlatform.xlWindows, "",
true, false, 0, true, false, false);
var workheets = _workbook.Worksheets;
_mainWorksheet = (Excel.Worksheet) workheets.Item[1];
}
public void DoStuff()
{
var cell = (Excel.Range)_mainWorksheet.Cells[4, "U"];
cell.set_Value(Missing.Value, 99);
}
public void Stop()
{
if (_workbook != null)
{
_workbook.Close(false, Missing.Value, Missing.Value);
_workbook = null;
_mainWorksheet = null;
}
if (_excelApp != null)
{
_excelApp.Quit();
_excelApp = null;
}
GC.Collect();
GC.WaitForPendingFinalizers();
}
public void Dispose()
{
Stop();
}
}
class Program
{
static void Main(string[] args)
{
using (var excelWorker = new ExcelWorker(@"C:\.....xlsx"))
{
excelWorker.Start();
excelWorker.DoStuff();
excelWorker.DoStuff();
}
Console.ReadKey();
}
}
}
您是否尝试过使用
FinalReleaseComObject
而不是ReleaseComObject
?可能与FinalReleaseComObject
重复。单元格[4,“U”]表达式创建了一个您看不到的接口引用,因此无法释放。像这样编写手动内存管理代码是非常非常不明智的。使用垃圾收集器,它永远不会出错。请确认。您是否尝试过使用FinalReleaseComObject
而不是ReleaseComObject
?可能与FinalReleaseComObject
重复。单元格[4,“U”]表达式创建了一个无法看到的接口引用,因此无法释放。像这样编写手动内存管理代码是非常非常不明智的。使用垃圾收集器,它永远不会出错。只要你确定。