我最近遇到的情况到目前为止我没有解释
尝试使用winform进行跨线程操作我写了一小段代码来更快地测试解决方案。 我有一个表单,包括进度条,DataGridView和Button
public MainForm()
{
this._progressBar = new ProgressBar { Dock = DockStyle.Top, };
this._button = new Button { Dock = DockStyle.Bottom, Text = @"&GO!" };
this._dataGridView = new DataGridView {Dock = DockStyle.Fill,};
this.Controls.Add(this.ProgressBar);
this.Controls.Add(this.Button);
this.Controls.Add(this.DataGridView);
this.WindowsFormsSynchronizationContext = WindowsFormsSynchronizationContext.Current as WindowsFormsSynchronizationContext;
this._records = new SpecialBindingList<Record>();
//this._records = new SpecialBindingList<Record>();
this.DataGridView.DataSource = this.Records;
this.Button.Click += this.button_Click;
}
该按钮有一个事件OnClick
private void button_Click(object sender, EventArgs e)
{
var dispatcherUI = Dispatcher.CurrentDispatcher;
Action action = () =>
{
while (true)
{
Task.Factory.StartNew(() =>
{
var value = (this.ProgressBar.Value == this.ProgressBar.Maximum)
? 0
: this.ProgressBar.Value + 1;
var record = new Record
{
A = DateTime.Now.Second.ToString(),
B = DateTime.Now.Millisecond.ToString()
};
if (Thread.CurrentThread != dispatcherUI.Thread)
{
dispatcherUI.BeginInvoke(new Action(() => { ProgressBar.Value = value; }), null);
}
this.WindowsFormsSynchronizationContext.Send((state) => this.Records.Add(record), null);
Thread.Sleep(100);
});
}
};
var task = new Task(action);
task.Start();
this.Button.Enabled = false;
}
它创建一个任务,填充进度条并向网格添加新行,然后启动它并禁用按钮。
问题是,我是否启动了这样的代码,在将记录添加到我的Bindinglist时,操作(state) => this.Records.Add(record)
将始终抛出InvalidOperationException
。
但是我意识到,如果我跳过this.Button.Enabled = false;
行,我的代码就会毫无问题地执行!
这对我来说有点奇怪,所以我想知道为什么修改按钮属性会在明显不相关的操作上创建异常