C#-如何将更新值从工作在不同线程中完成的类发送回form类

C#-如何将更新值从工作在不同线程中完成的类发送回form类,c#,multithreading,C#,Multithreading,我正在处理一个应用程序的启动/加载屏幕,我希望有一个进度条和一个标签,它将通知用户当前进程,例如连接到数据库、加载用户设置、检索x数据、检索y数据 我以前在VB中只做了一点点BackGroundWorker的工作,而在C中什么都没有,所以我有点困惑从哪里开始,因为在C中它看起来很不一样 我希望表单类保持简单,以便只调用不同线程上不同类的特定方法 我主要需要知道如何从执行该工作的类中更新GUI,因为我认为我可以通过以下代码计算线程本身: using System; using Sy

我正在处理一个应用程序的启动/加载屏幕,我希望有一个进度条和一个标签,它将通知用户当前进程,例如连接到数据库、加载用户设置、检索x数据、检索y数据

我以前在VB中只做了一点点BackGroundWorker的工作,而在C中什么都没有,所以我有点困惑从哪里开始,因为在C中它看起来很不一样

我希望表单类保持简单,以便只调用不同线程上不同类的特定方法

我主要需要知道如何从执行该工作的类中更新GUI,因为我认为我可以通过以下代码计算线程本身:

    using System;
    using System.Threading;
    
    public class ThreadWork
    {
       public static void DoWork()
       {
          for(int i = 0; i<3;i++) {
             Console.WriteLine("Working thread...");
             Thread.Sleep(100);
          }
       }
    }

class ThreadTest
{
   public static void Main()
   {
      Thread thread1 = new Thread(ThreadWork.DoWork);
      thread1.Start();
      for (int i = 0; i<3; i++) {
         Console.WriteLine("In main.");
         Thread.Sleep(100);
      }
   }
}
使用系统;
使用系统线程;
公营丝线
{
公共静态无效工作()
{

对于(int i=0;i,尽管Mitch的答案会起作用。您也可以使用TaskScheduler处理后台工作,然后回复UI:

public static void Main()
        {
            TaskScheduler uiScheduler = TaskScheduler.FromCurrentSynchronizationContext();
            Task.Factory.StartNew(() => DoBackgroundWork(uiScheduler));
        }

        private static void DoBackgroundWork(TaskScheduler uiScheduler)
        {
            // Do background stuff here...

            Task.Factory.StartNew(() =>
            {
                // Respond back to UI here
                Console.WriteLine("Doing work");
                // Or if you have to change GUI, let's say a label value;
                label1.Text = "Text changed by background Task";

            }, CancellationToken.None, TaskCreationOptions.None, uiScheduler);
            
            // Some other background work
        }
您可以使用此方法将工作卸载到
线程池
线程,并使用对象将进度从后台线程报告到UI。您还可以使用此方法以简单的方式编写代码。以下是一个示例:

private async void Form_Load(object sender, EventArgs e)
{
    IProgress<string> progress = new Progress<string>(message =>
    {
        Label1.Text = message;
    });

    var result = await Task.Run(() =>
    {
        progress.Report("Connecting to database...");
        ConnectToDatabase();
        progress.Report("Loading user settings...");
        LoadUserSettings();
        progress.Report("Retrieving x data...");
        return RetrieveXData();
    });

    // At this point the background processing has completed
    Label1.Text = $"Done! ({result})";
}
private async void Form\u加载(对象发送方,事件参数e)
{
i进度=新进度(消息=>
{
标签1.文本=消息;
});
var result=等待任务。运行(()=>
{
进度报告(“连接到数据库…”);
ConnectToDatabase();
进度报告(“正在加载用户设置…”);
LoadUserSettings();
进度报告(“检索x数据…”);
返回RetrieveXData();
});
//此时,后台处理已完成
Label1.Text=$“完成!({result})”;
}

如果要以不同的时间间隔报告异构数据,则可以使用多个
进度
对象(例如
进度
进度
等)。您也可以使用复杂类型进行报告,例如
进度

为什么不使用backgroundworker?如果在C中与vb.netOh不一样,它应该非常相似。亲爱的……我甚至没有想到检查backgroundworker在C中是否存在……它是存在的。它是相同的!“我甚至没有想到检查backgroundworker在C中是否存在。”…如果它是一个.NET库(它是),那么它将适用于所有.NET语言。这是.NET的一个很好的优点-当你使用这样的库时,你使用的是编译后的代码,而不是源代码,因此它最初使用的语言(以及你用来与之交互的语言)与此无关。@MitchWheat我使用了您关于使用后台工作人员的建议。您想将其作为答案发布,以便我将其标记为此问题的解决方案吗?