在下面的代码中,我有一个名为GetExcelData
的长期运行的过程。完成后,我想显示一个对话框,将其内容保存到TXT文件中。
问题是,在调试时,出现以下错误:
当前线程必须设置为单线程单元(STA)模式
才能进行OLE调用。确保您的Main函数具有
STAThreadAttribute标记在上面。仅在以下情况下引发此异常:
调试器已附加到该进程。
这是我的代码。错误出现在读取saveFileDialog1.ShowDialog();
的行上
FileInfo existingFile = new FileInfo("C:\\MyExcelFile.xlsx");
ConsoleApplication2.Program.ExcelData data = ConsoleApplication2.Program.GetExcelData(existingFile, _worker);
var json = new JavaScriptSerializer().Serialize(data);
SaveFileDialog saveFileDialog1 = new SaveFileDialog();
saveFileDialog1.Filter = "txt files (*.txt)|*.txt|All files (*.*)|*.*";
saveFileDialog1.ShowDialog();
if (saveFileDialog1.FileName != "")
{
File.WriteAllText(saveFileDialog1.FileName, json);
}
我尝试将
[STAThread]
属性添加到我从中调用的方法中,但是它似乎没有用。请让我提供更多代码,以进一步明确我要执行的操作:
WPF项目中存在以下内容,该项目引用了我的Console项目:
private BackgroundWorker _backgroundWorker = new BackgroundWorker();
public MainWindow()
{
InitializeComponent();
// Set up the BackgroundWorker.
this._backgroundWorker.WorkerReportsProgress = true;
this._backgroundWorker.WorkerSupportsCancellation = true;
this._backgroundWorker.DoWork += new DoWorkEventHandler(bw_DoWork);
this._backgroundWorker.ProgressChanged +=
new ProgressChangedEventHandler(bw_ProgressChanged);
}
private void Button_Click(object sender, RoutedEventArgs e)
{
if (this._backgroundWorker.IsBusy == false)
{
this._backgroundWorker.RunWorkerAsync();
}
e.Handled = true;
}
void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
// Set the Value porperty when porgress changed.
this.progressBar1.Value = (double)e.ProgressPercentage;
}
void bw_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker _worker = sender as BackgroundWorker;
if (_worker != null)
{
FileInfo existingFile = new FileInfo("C:\\MyExcelFile.xlsx");
ConsoleApplication2.Program.ExcelData data = ConsoleApplication2.Program.GetExcelData(existingFile, _worker);
var json = new JavaScriptSerializer().Serialize(data);
SaveFileDialog saveFileDialog1 = new SaveFileDialog();
saveFileDialog1.Filter = "txt files (*.txt)|*.txt|All files (*.*)|*.*";
saveFileDialog1.ShowDialog();
if (saveFileDialog1.FileName != "")
{
File.WriteAllText(saveFileDialog1.FileName, json);
}
}
}
最佳答案
将与UI交互的代码移动到处理UI元素的相同线程。通过RunWorkerCompleted事件实现此目的的最简单方法
this._backgroundWorker.RunWorkerCompleted +=
new RunWorkerCompletedEventHandler(bw_WorkComplete);
....
void bw_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker _worker = sender as BackgroundWorker;
if (_worker != null)
{
FileInfo existingFile = new FileInfo("C:\\MyExcelFile.xlsx");
ConsoleApplication2.Program.ExcelData data = ConsoleApplication2.Program.GetExcelData(existingFile, _worker);
e.Result = new JavaScriptSerializer().Serialize(data);
}
}
private void bw_WorkComplete(object sender, RunWorkerCompletedEventArgs e)
{
SaveFileDialog saveFileDialog1 = new SaveFileDialog();
saveFileDialog1.Filter = "txt files (*.txt)|*.txt|All files (*.*)|*.*";
saveFileDialog1.ShowDialog();
if (saveFileDialog1.FileName != "")
{
string json = e.Result.ToString();
File.WriteAllText(saveFileDialog1.FileName, json);
}
}
在DoWork方法中,将json字符串保存在DoWorkEventArgs类的e.Result属性中,然后从具有相同名称的RunWorkerCOmpletedEventArgs属性的RunWorkerCompleted事件中检索它。