Visual Studio 2008 for Excel 2003 で、ユーザーの選択に基づいて複数の Excel シートからオブジェクト データを消去する Excel アドインを作成しました。アドインは正常に実行されますが、さまざまなアクションでランダムな間隔で実行すると、Excel がクラッシュします。以下のコードには、進行状況バー、バックグラウンド ワーカー、およびファイルを開くダイアログ (ofd) を備えた Windows フォームが含まれています。この例外がスローされます: Microsoft.VisualStudio.Debugger.Runtime.Main.ThrowCrossThreadMessageException
(明らかでない場合) でのMain()
イベント中にthis.progressbar1.Text
。この問題を解決するためにいくつかの方法を試しましたが、このコード スニペットに反映されている可能性があります。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Excel = Microsoft.Office.Interop.Excel;
using System.Runtime.InteropServices;
using System.Threading;
using Microsoft.Win32;
namespace WindowsFormApplication
{
public partial class Form3 : Form
{
private int highestPercentageReached = 0;
private bool skipreadonly = true;
public Form3()
{
InitializeComponent();
}
private void Form3_Load(object sender, EventArgs e)
{
Thread newThread = new Thread(new ThreadStart(main));
newThread.SetApartmentState(ApartmentState.STA);
newThread.Start();
}
[STAThread]
private void main()
{
if ((bool)Invoke(new ExcelSelectHandler(ExcelSelect)))
{
Invoke(new MethodInvoker(this.Show));
backgroundWorker1.RunWorkerAsync();
}
else
{
Invoke(new MethodInvoker(this.Close));
}
}
private void Form3_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == (Char)Keys.Escape)
{
backgroundWorker1.CancelAsync();
}
}
private delegate bool ExcelSelectHandler();
private bool ExcelSelect()
{
Invoke(new MethodInvoker(this.Hide));
ofd.Title = "Excel Reset";
ofd.Multiselect = true;
ofd.FileName = "";
ofd.Filter = "Excel Files|*.xls;*.xlsx;*.xlt;*.xltx;*.xlsb;*.xlsm;*.xltm";
DialogResult result = ofd.ShowDialog();
return result == DialogResult.OK;
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
DataRemove(worker, e);
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
MethodInvoker proginvoke = delegate
{
progressBar1.Value = e.ProgressPercentage;
};
progressBar1.BeginInvoke(proginvoke);
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Error != null)
{
MessageBox.Show(e.Error.Message);
}
else if (e.Cancelled)
{
Invoke(new MethodInvoker(this.Close));
}
else
{
Invoke(new MethodInvoker(this.Close));
}
}
private void DataRemove(BackgroundWorker worker, DoWorkEventArgs e)
{
try
{
object missing = System.Reflection.Missing.Value;
int k = ofd.FileNames.Length;
int l = 0;
Excel.Application eapp = ThisAddIn.xlApplication;
Excel.Workbook eawb = eapp.ActiveWorkbook;
Excel.Application xlApp = new Microsoft.Office.Interop.Excel.Application();
xlApp.ScreenUpdating = false;
xlApp.Visible = false;
Excel.Workbook xlWorkbook;
foreach (var filename in ofd.FileNames)
{
if (l < k)
{
if (filename != eawb.FullName)
{
xlWorkbook = xlApp.Workbooks.Open(ofd.FileNames[l].ToString(), missing, missing, missing, missing, missing, true, missing, missing, missing, true, missing, missing, missing, missing);
Excel.Worksheet xlWorksheet = (Excel.Worksheet)xlApp.ActiveSheet;
Excel.ListRows xlRows = (Excel.ListRows)xlWorksheet.ListObjects;
if (xlWorkbook.ReadOnly)
{
if (skipreadonly)
{
xlWorkbook.Close(false, missing, missing);
}
else
{
Invoke(new MethodInvoker(this.Hide));
if (MessageBox.Show("Excel document '" + ofd.SafeFileNames[l].ToString() + "' is either opened or marked read only and data will not removed from this file. Do you want to ignore this file and continue removing data?", "Data Remover", MessageBoxButtons.YesNo) == DialogResult.No)
{
Invoke(new MethodInvoker(this.Show));
if (worker.WorkerSupportsCancellation == true)
{
worker.CancelAsync();
xlWorkbook.Close(false, missing, missing);
break;
}
}
else
{
Invoke(new MethodInvoker(this.Show));
xlWorkbook.Close(false, missing, missing);
}
}
}
else
{
if (xlRows.Count > 0)
{
foreach (Excel.ListRow xlRow in xlRows)
{
xlRow.Delete();
}
}
xlWorkbook.Save();
xlWorkbook.Close(true, missing, missing);
}
Marshal.ReleaseComObject(xlRows);
Marshal.ReleaseComObject(xlWorksheet);
Marshal.ReleaseComObject(xlWorkbook);
}
else
{
Excel.Worksheet exlWorksheet = (Excel.Worksheet)eawb.ActiveSheet;
Excel.ListRows xlRows = (Excel.ListRows)exlWorksheet.ListObjects;
foreach (Excel.ListRow xlRow in xlRows)
{
xlRow.Delete();
}
}
l += 1;
}
if (worker.CancellationPending)
{
e.Cancel = true;
break;
}
else
{
int percentComplete = l / k * 100;
highestPercentageReached = percentComplete;
worker.ReportProgress(percentComplete);
}
}
xlApp.Quit();
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
GC.WaitForPendingFinalizers();
Marshal.FinalReleaseComObject(xlApp);
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
}
}