C# 有没有线程安全调用的好例子?
我有一个带有大量WinForm控件的函数C# 有没有线程安全调用的好例子?,c#,winforms,multithreading,c#-4.0,parallel-processing,C#,Winforms,Multithreading,C# 4.0,Parallel Processing,我有一个带有大量WinForm控件的函数LoadData,它将数据从数据库加载到控件中。 现在它变得非常慢,我应该使用线程,如果是的话,请建议一个好的样品,我已经尝试了 但它对我没有用处,需要对我的代码进行大量更改。您可以使用.NET 4中的TPL以一种可能更简单的方式处理此问题。您只需传递一个适当的任务调度器。使用从UI上下文创建的TaskScheduler,任何调用都可以轻松地包装到Task中,该任务将根据需要在UI线程上执行 有关详细信息,请参阅我的。我假设您有许多与UI交互的代码,并且您
LoadData
,它将数据从数据库加载到控件中。
现在它变得非常慢,我应该使用线程,如果是的话,请建议一个好的样品,我已经尝试了
但它对我没有用处,需要对我的代码进行大量更改。您可以使用.NET 4中的TPL以一种可能更简单的方式处理此问题。您只需传递一个适当的
任务调度器
。使用从UI上下文创建的TaskScheduler
,任何调用都可以轻松地包装到Task
中,该任务将根据需要在UI线程上执行
有关详细信息,请参阅我的。我假设您有许多与UI交互的代码,并且您希望从后台线程执行这些操作 您可以添加如下方法:
private static void UpdateControl(Control control, Action action)
{
if (control.InvokeRequired)
control.Invoke(action);
else
action();
}
用法:
旧的
新的
或扩展方法,使用法更短
public static class ControlExtension
{
public static void UpdateControl(this Control control, Action<Control> action)
{
if (control.InvokeRequired)
control.Invoke((Action)(() => action(control)));
else
action(control);
}
}
退房
var bw=newbackgroundworker();
bw.DoWork+=(s,e)=>e.Result=getAllBoxers();
bw.RunWorkerCompleted+=(s,e)=>
{
var boxers=e.结果为列表;
dgvBoxers.DataSource=boxers;
};
RunWorkerAsync();
确保永远不要在
DoWork
中执行任何影响GUI的操作,因为WinForms不是线程安全的。您必须精确确定加载的数据类型和方式;一般来说,线程化几乎总是需要大量的返工,特别是如果核心代码设计时没有考虑线程化…你最好看看你加载了多少数据,看看你是否找不到加载子集的方法。非常简洁的回答。扩展方法的主要候选者IYAM@AlexAza:如果函数有8/10个控件,或者可能超过8/10个,那么control.invokererequired和control.Invoke会同时执行..?@Akhil-我不太明白invokererequired
和Invoke
一个接一个地执行,而不是同时执行<如果调用来自非UI线程,则code>control.invokererequired将返回true。
UpdateControl(textbox, () => { textBox.Text = "Something" });
public static class ControlExtension
{
public static void UpdateControl(this Control control, Action<Control> action)
{
if (control.InvokeRequired)
control.Invoke((Action)(() => action(control)));
else
action(control);
}
}
textBox.UpdateControl(arg => arg.Text = "Something");
var bw = new BackgroundWorker();
bw.DoWork += (s, e) => e.Result = getAllBoxers();
bw.RunWorkerCompleted += (s, e) =>
{
var boxers = e.Result as List<Boxer>;
dgvBoxers.DataSource = boxers;
};
bw.RunWorkerAsync();