使用任务并行库时如何修复跨线程错误?
How to Fix Cross-thread error When using Task Parallel library?
List<Task> tasks = new List<Task>();
tasks.Add(Task.Run(() => functionA()));
tasks.Add(Task.Run(() => functionB()));
tasks.Add(Task.Run(() => functionC()));
function A(){
List<string>lstResult =Get list ();
control.DataSource =lstResult ;
control.Databind();
}
function B(){
List<string>lstResult =Get list ();
control.DataSource =lstResult ;
control.Databind();
}
function C(){
List<string>lstResult =Get list ();
control.DataSource =lstResult ;
control.Databind();
}
在这里,由于并发问题,我得到 Stack Empty 异常。这个怎么解决。我遇到过这个 Stack Empty Excetpion 但没有提到如何克服这个问题。
您的 control
对象可以同时被多个线程访问。要解决此问题,您必须像这样使用 MethodInvoker
:
function A(){
List<string> lstResult =Getlist();
Invoke(new MethodInvoker(delegate
{
control.DataSource =lstResult ;
control.Databind();
}));
}
您不能在任何操作系统中从另一个线程修改 UI。如果使用 async/await
并且 Task.Run
将 移动到 函数中,则此代码可以简化很多,例如:
async Task functionA(){
var results= await Task.Run(()=>Getlist1();
control1.DataSource =results ;
control1.Databind();
}
async Task functionB(){
var results= await Task.Run(()=>Getlist2();
control2.DataSource =results ;
control2.Databind();
}
async Task functionC(){
var results= await Task.Run(()=>Getlist3();
control3.DataSource =results ;
control3.Databind();
}
var tasks = await Task.WhenAll( functionA(),
functionB(),
functionC());
await
等待已经异步的操作完成而不阻塞。当该操作完成时,它 returns 执行到原始线程,在本例中为 UI 线程
List<Task> tasks = new List<Task>();
tasks.Add(Task.Run(() => functionA()));
tasks.Add(Task.Run(() => functionB()));
tasks.Add(Task.Run(() => functionC()));
function A(){
List<string>lstResult =Get list ();
control.DataSource =lstResult ;
control.Databind();
}
function B(){
List<string>lstResult =Get list ();
control.DataSource =lstResult ;
control.Databind();
}
function C(){
List<string>lstResult =Get list ();
control.DataSource =lstResult ;
control.Databind();
}
在这里,由于并发问题,我得到 Stack Empty 异常。这个怎么解决。我遇到过这个 Stack Empty Excetpion 但没有提到如何克服这个问题。
您的 control
对象可以同时被多个线程访问。要解决此问题,您必须像这样使用 MethodInvoker
:
function A(){
List<string> lstResult =Getlist();
Invoke(new MethodInvoker(delegate
{
control.DataSource =lstResult ;
control.Databind();
}));
}
您不能在任何操作系统中从另一个线程修改 UI。如果使用 async/await
并且 Task.Run
将 移动到 函数中,则此代码可以简化很多,例如:
async Task functionA(){
var results= await Task.Run(()=>Getlist1();
control1.DataSource =results ;
control1.Databind();
}
async Task functionB(){
var results= await Task.Run(()=>Getlist2();
control2.DataSource =results ;
control2.Databind();
}
async Task functionC(){
var results= await Task.Run(()=>Getlist3();
control3.DataSource =results ;
control3.Databind();
}
var tasks = await Task.WhenAll( functionA(),
functionB(),
functionC());
await
等待已经异步的操作完成而不阻塞。当该操作完成时,它 returns 执行到原始线程,在本例中为 UI 线程