Nie*_*sma 6 c# multithreading winforms excel-dna
我有一个带有backgroundWorker的WinForm:
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 SeoTools.Utils;
namespace SeoTools.UI
{
public partial class UIProgress : Form
{
public UIProgress(DoWorkEventHandler doWorkEventHandler, RunWorkerCompletedEventHandler runWorkerCompletedEventHandler)
{
InitializeComponent();
this.backgroundWorker.WorkerReportsProgress = true;
this.backgroundWorker.WorkerSupportsCancellation = true;
this.backgroundWorker.DoWork += doWorkEventHandler;
this.backgroundWorker.RunWorkerCompleted += runWorkerCompletedEventHandler;
}
public void Start()
{
var foo = SynchronizationContext.Current;
backgroundWorker.RunWorkerAsync();
}
private void btnStop_Click(object sender, EventArgs e)
{
btnStop.Enabled = false;
btnStop.Text = "Stopping...";
backgroundWorker.CancelAsync();
}
private void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
try
{
wdgProgressBar.Value = e.ProgressPercentage;
if (this.Visible == false)
{
this.ShowDialog();
this.Update();
}
}
catch (InvalidOperationException) {}
}
private void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
this.Hide(); //Here I get a InvalidOperationException
this.Dispose();
}
}
}
Run Code Online (Sandbox Code Playgroud)
我第一次运行它运行正常.但第二次InvalidOperationException打电话时我得到了this.Hide().
"附加信息:跨线程操作无效:控制'UIProgress'从其创建的线程以外的线程访问."
奇怪的是第一次运行foo在Start()中是一个WindowsFormsSyncronizationContext,但在第二次尝试它是一个System.Threading.SyncronizationContext.
我正在编写的应用程序是一个ExcelDna插件.
编辑
Start()被调用如下:
UIProgress uiProgress = new UIProgress(
delegate(object sender, DoWorkEventArgs args)
{
....
},
delegate(object sender, RunWorkerCompletedEventArgs args)
{
...
}
);
uiProgress.Start();
Run Code Online (Sandbox Code Playgroud)
必须从在UI线程上运行的代码调用Start()方法,以允许BackgroundWorker正常运行.这不是你得到这个例外的时候.为您的方法添加保护代码,以便您可以诊断此事故:
public void Start()
{
if (Thread.CurrentThread.GetApartmentState() != ApartmentState.STA) {
throw new InvalidOperationException("Bug! Code called from a worker thread");
}
backgroundWorker.RunWorkerAsync();
}
Run Code Online (Sandbox Code Playgroud)
现在,您可以在throw语句上设置断点,并使用调试器的"调用堆栈"窗口来查找发生这种情况的原因.
| 归档时间: |
|
| 查看次数: |
1713 次 |
| 最近记录: |