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