110,546
社区成员
发帖
与我相关
我的任务
分享
System.InvalidOperationException:“线程间操作无效: 从不是创建控件“btnResult”的线程访问它。”
你调试的过程是什么?指定断点或者单步调试了吗?看到并且断言了了 result 输出结果是否正确了吗?
贴出来实际测试结果截图。 private void Form1_Load(object sender, EventArgs e)
{
//Task.Factory.StartNew(() =>
//{
// Thread.Sleep(2000);
// //this.button1.Text="ss";
//}).ContinueWith(t => this.button1.Text = "11", TaskScheduler.FromCurrentSynchronizationContext());
Task<int> t1 = new Task<int>(() =>
{
int result = 3;
this.button1.Text = result.ToString();
for (; result <= 10; result++)
result++;
return result;
});
t1.Start();
t1.ContinueWith(task => { Thread.Sleep(3000); this.button1.Text = task.Result.ToString(); },TaskScheduler.FromCurrentSynchronizationContext());
//ThreadPool.QueueUserWorkItem((obj) => this.button1.Text = "ss");
}
}
就是很简单的测试程序,直接运行不会报错,并且界面也会更新,后面的ContinueWith会阻塞UI线程3秒。这个没问题,但是前面的代码也没报错直接成功更新了。System.InvalidOperationException:“线程间操作无效: 从不是创建控件“textBox1”的线程访问它。”
你应该一次性地贴出准确地截图、或者源代码来,但凡动手很迅速的人贴图是也总是能一步到位说明自己的问题环境。不要像多么舍不得把自己的代码公开似地。
//Task
Task<int> t1 = new Task<int>(() =>
{
int result = 3;
this.btnResult.Text = result.ToString();
for (; result <= 10; result++)
result++;
return result;
});
t1.Start();
//ThreadPool
ThreadPool.QueueUserWorkItem((obj) => this.btnResult.Text = "ss");
//Task
Task<int> t1 = new Task<int>(() =>
{
int result = 3;
this.btnResult.Text = result.ToString();
for (; result <= 10; result++)
result++;
return result;[code=csharp]
});
t1.Start();
//ThreadPool
ThreadPool.QueueUserWorkItem((obj) => this.btnResult.Text = "ss");
[/code]
我知道如果用Task.ContinueWith方法的带TaskScheduler重载版本,传入TaskScheduler.FromCurrentSynchronizationContext()的话,ContinueWith中执行的操作会由UI线程去执行,不会报跨线程调用异常。但是上面的Task的构造函数中并没有带这种调度器的参数,为什么也不会报跨线程访问UI异常。