相关疑难解决方法(0)

了解.NET中的垃圾收集

考虑以下代码:

public class Class1
{
    public static int c;
    ~Class1()
    {
        c++;
    }
}

public class Class2
{
    public static void Main()
    {
        {
            var c1=new Class1();
            //c1=null; // If this line is not commented out, at the Console.WriteLine call, it prints 1.
        }
        GC.Collect();
        GC.WaitForPendingFinalizers();
        Console.WriteLine(Class1.c); // prints 0
        Console.Read();
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,即使main方法中的变量c1超出范围并且在GC.Collect()调用时没有被任何其他对象进一步引用,为什么它没有在那里完成?

.net c# garbage-collection

161
推荐指数
2
解决办法
5万
查看次数

给定Range对象时,遍历一系列单元格中的每个单元格

假设我有以下代码:

Sub TestRangeLoop()
    Dim rng As Range
    Set rng = Range("A1:A6")

    ''//Insert code to loop through rng here
End Sub
Run Code Online (Sandbox Code Playgroud)

我希望能够Range为每个指定的单元格迭代一组对象rng.从概念上讲,我想这样做:

For Each rngCell As Range in rng
     ''//Do something with rngCell
Next
Run Code Online (Sandbox Code Playgroud)

我知道我可以通过手动解析rng.Address和构建Range对象来解决这个问题,但我希望有一种更直接的方法,不涉及字符串解析.

excel vba excel-vba

54
推荐指数
2
解决办法
28万
查看次数

如何在按钮点击时立即将dataGridView数据导出到Excel?

我的数据网格视图中有10k行和15列.我想将此数据导出到excel表单o按钮.我已经尝试过以下代码.

private void btExport_Click(object sender, EventArgs e)
    {
        Microsoft.Office.Interop.Excel._Application app  = new Microsoft.Office.Interop.Excel.Application();
        Microsoft.Office.Interop.Excel._Workbook workbook =  app.Workbooks.Add(Type.Missing);        
        Microsoft.Office.Interop.Excel._Worksheet worksheet = null;                   
        app.Visible = true;
        worksheet = workbook.Sheets["Sheet1"];
        worksheet = workbook.ActiveSheet;                  
        for(int i=1;i<dataGridView1.Columns.Count+1;i++)
        {
             worksheet.Cells[1, i] = dataGridView1.Columns[i-1].HeaderText;
        }    
        for (int i=0; i < dataGridView1.Rows.Count-1 ; i++)
        {
            for(int j=0;j<dataGridView1.Columns.Count;j++)
            {
                if (dataGridView1.Rows[i].Cells[j].Value != null)
                {
                    worksheet.Cells[i + 2, j + 1] = dataGridView1.Rows[i].Cells[j].Value.ToString();
                }
                else
                {
                    worksheet.Cells[i + 2, j + 1] = "";
                }
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

这对我有用, …

c# datagridview copy export-to-excel export-to-csv

41
推荐指数
4
解决办法
16万
查看次数

*每个*Excel互操作对象是否需要使用Marshal.ReleaseComObject释放?

编辑

另请参阅如何正确清理Excel互操作对象?.我最近遇到了这个问题,它提供了很多关于如何正确处理COM对象的问题的见解.绝对检查超出第一个(标记的)答案,因为其他答案超出了简单的"不要使用两个点"和" ReleaseComObject用于每个com对象"的建议.

我首先重新审视了这个问题,因为我意识到尽管注册和处理所有COM对象非常彻底,但我的Excel实例仍然没有得到妥善处理.事实证明,有些方法可以创建完全不明显的COM对象(即,即使您从不使用两个点,也可以错过COM对象).此外,即使您是彻底的,如果您的项目增长超过一定的大小,错过COM对象的机会接近100%.当发生这种情况时,很难找到你错过的那个.上面链接的问题的答案提供了一些其他技术,以确保Excel实例肯定关闭.同时,我对我ComObjectManager(下面)做了一个小的(但重要的)更新,以反映我从上面链接的问题中学到的东西.

原始问题

我已经看到了几个Marshal.ReleaseComObject()与Excel Interop对象一起使用的例子(即来自命名空间Microsoft.Office.Interop.Excel的对象),但我已经看到它用于不同程度.

我想知道我是否可以逃避这样的事情:

var application = new ApplicationClass();
try
{
    // do work with application, workbooks, worksheets, cells, etc.
}
finally
{
    Marashal.ReleaseComObject(application)
}
Run Code Online (Sandbox Code Playgroud)

或者,如果我需要释放创建的每个对象,如此方法:

public void CreateExcelWorkbookWithSingleSheet()
{
    var application = new ApplicationClass();
    var workbook = application.Workbooks.Add(_missing);
    var worksheets = workbook.Worksheets;
    for (var worksheetIndex = 1; worksheetIndex < worksheets.Count; worksheetIndex++)
    {
        var worksheet = (WorksheetClass)worksheets[worksheetIndex];
        worksheet.Delete();
        Marshal.ReleaseComObject(worksheet);
    }
    workbook.SaveAs(
        WorkbookPath, _missing, _missing, _missing, _missing, _missing,
        XlSaveAsAccessMode.xlExclusive, _missing, …
Run Code Online (Sandbox Code Playgroud)

.net c# com excel office-interop

28
推荐指数
2
解决办法
4776
查看次数

Interop进程后无法关闭Excel.exe

我遇到了Excel Interop的问题.

即使我重新发布实例,Excel.exe也不会关闭.

这是我的代码:

using xl = Microsoft.Office.Interop.Excel;


xl.Application excel = new xl.Application();
excel.Visible = true;
excel.ScreenUpdating = false;
if (wordFile.Contains(".csv") || wordFile.Contains(".xls"))
{
   //typeExcel become a string of the document name
   string typeExcel = wordFile.ToString();
   xl.Workbook workbook = excel.Workbooks.Open(typeExcel,
                                                oMissing,  oMissing,  oMissing,  oMissing,
                                                oMissing,  oMissing,  oMissing,  oMissing,
                                                oMissing,  oMissing,  oMissing,  oMissing,
                                                oMissing,  oMissing);
   object outputFileName = null;
   if (wordFile.Contains(".xls"))
   {
     outputFileName = wordFile.Replace(".xls", ".pdf");
   }
   else if (wordFile.Contains(".csv"))
   {
     outputFileName = wordFile.Replace(".csv", ".pdf");
   }

   workbook.ExportAsFixedFormat(XlFixedFormatType.xlTypePDF, outputFileName, 
                                 XlFixedFormatQuality.xlQualityStandard, oMissing,
                                 oMissing, …
Run Code Online (Sandbox Code Playgroud)

c# excel-interop winforms

28
推荐指数
6
解决办法
5万
查看次数

使用IDisposable清理Excel Interop对象

在我的公司中,发布Excel Interop Objects的常用方法是使用IDisposable,方法如下:

Public Sub Dispose() Implements IDisposable.Dispose
    If Not bolDisposed Then
        Finalize()
        System.GC.SuppressFinalize(Me)
    End If
End Sub

Protected Overrides Sub Finalize()
    _xlApp = Nothing
    bolDisposed = True
    MyBase.Finalize()
End Sub
Run Code Online (Sandbox Code Playgroud)

IDisposable构造函数中以下列方式创建的位置:

Try
    _xlApp = CType(GetObject(, "Excel.Application"), Excel.Application)
Catch e As Exception
    _xlApp = CType(CreateObject("Excel.Application"), Excel.Application) 
End Try
Run Code Online (Sandbox Code Playgroud)

并且客户端使用_xlApp执行有关excel互操作对象的代码.

我们完全避免使用双点规则.现在我开始研究如何重新发布(Excel)互操作对象以及我发现的几乎所有关于它的讨论如何正确清理excel互操作对象释放Excel对象主要使用Marshal.ReleaseComObject(),它们都没有使用IDisposable接口.

我的问题是:使用IDisposable Interace释放excel互操作对象有什么缺点吗?如果是这样,这些不利因素是什么.

.net vb.net excel interop com-interop

25
推荐指数
1
解决办法
7778
查看次数

C# - 如何以编程方式添加Excel工作表 - Office XP/2003

我刚刚开始通过C#调整Excel,以便能够自动创建,并添加到Excel文件中.

我可以打开文件并更新其数据并浏览现有的工作表.我的问题是如何添加新表?

我试过了:

Excel.Worksheet newWorksheet;
newWorksheet = (Excel.Worksheet)excelApp.ThisWorkbook.Worksheets.Add(
                Type.Missing, Type.Missing, Type.Missing, Type.Missing);
Run Code Online (Sandbox Code Playgroud)

但我得到COM异常,我的谷歌搜索没有给我任何答案.

来自HRESULT的异常:0x800A03EC来源是:"Interop.Excel"

我希望有人能够让我摆脱困境.

c# com excel worksheet office-interop

23
推荐指数
2
解决办法
10万
查看次数

调用Word.Documents.Add - Word .NET Interop后,WinWord.exe不会退出

我遇到了经典场景,当在.NET中创建Word COM对象时(通过Microsoft.Office.Interop.Word程序集),即使我正确关闭并释放对象,WinWord进程也不会退出.

我已经将其缩小到使用Word.Documents.Add()方法.我可以在没有问题的情况下以其他方式使用Word(打开文档,修改内容等),并在我告诉它时退出WinWord.exe.一旦我使用Add()方法(并且仅在添加模板时),该过程就会继续运行.

这是一个简单的例子,它可以重现这个问题:

Dim word As New Word.Application()
word.Visible = False

Dim documents As Word.Documents = word.Documents
Dim doc As Word.Document = documents.Add(Template:=CObj(templatePath), NewTemplate:=False, DocumentType:=Word.WdNewDocumentType.wdNewBlankDocument, Visible:=False)

'' dispose objects
doc.Close()
While (Marshal.ReleaseComObject(doc) <> 0)
End While
doc = Nothing

While (Marshal.ReleaseComObject(documents) <> 0)
End While
documents = Nothing

word.Quit()
While (Marshal.ReleaseComObject(word) <> 0)
End While
word = Nothing

GC.Collect()
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,我正在创建和正确处理对象,甚至采取额外的步骤来循环Marsha.ReleaseComObject,直到它返回正确的代码.在其他方面使用Word对象很好,只是那些讨厌的Documents.Add让我感到悲伤.是否有另一个在此过程中创建的对象需要引用和处理?我需要遵循另一个处理步骤吗?别的什么?非常感谢您的帮助 :)

Update: 我在处理步骤结束时尝试了GC.Collect,但仍然没有运气.

Update 2: 我已经将问题缩小到使用自定义模板.当我调用Documents.Add(...)时,我为新文档指定了一个自定义模板.如果我不这样做而是调用没有参数的Add(),那么问题就不会发生.

.net com interop ms-word office-interop

20
推荐指数
2
解决办法
2万
查看次数

保护Excel工作簿中的代码?

我想生成一个包含专有公式和其他知识产权的Excel工作簿.我很可能使用C#在Visual Studio 2010中生成此工作簿.

这些项目中的代码有多受保护?C#中的反射问题仍然适用于这些工作簿项目吗?如果是这样,是否有针对这些类型工作簿的混淆工具?

添加到这个问题 - 好的'ole VBA怎么样?如果我们要去VBA路线,有没有办法保护这些代码呢?

c# excel visual-studio

18
推荐指数
3
解决办法
8515
查看次数

正确的释放COM对象的方法?

有时当我结束应用程序并尝试释放一些COM对象时,我会在调试器中收到警告:

RaceOnRCWCleanUp 被发现了

如果我编写一个使用COM对象的类,我是否需要实现IDisposable并调用Marshal.FinalReleaseComObject它们IDisposable.Dispose才能正确释放它们?

如果Dispose没有手动调用,我还需要在终结器中释放它们还是GC会自动释放它们?现在我打电话Dispose(false)给终结者,但我想知道这是否正确.

我使用的COM对象也有一个类侦听的事件处理程序.显然,事件是在另一个线程上引发的,所以如果在处理类时触发它,如何正确处理呢?

.net c# com

16
推荐指数
3
解决办法
2万
查看次数