C# 有没有线程安全调用的好例子?

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交互的代码,并且您

我有一个带有大量WinForm控件的函数
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();