C# Winform 多线程序列
我对 C# 和一般编码相对较新。我正在尝试编写一个具有一定逻辑并且还用进度条指示进度的程序。我正在 Main() 中启动一个线程来执行我的所有业务逻辑。它的事件在我需要更新进度条的点处触发。
Form 对象订阅业务逻辑事件,并具有调用以更新进度条和文本标签的线程安全委托。
我的问题是,当表单在主线程中启动时,我必须在 Application.Run() 之前启动业务逻辑线程。当触发第一个 ProgressUpdate 事件时,Form 对象仍然不存在。我想一个 hacky 方法是在第二个线程中添加 Thread.Sleep(100) ,但我不喜欢那样。我该如何解决这个问题?我是否走在完全错误的轨道上? (我说得通吗?)
Form1 theForm = new Form1();
CreateReport theCreateReport = new CreateReport();
Thread t = new Thread(new ThreadStart(theCreateReport.DoProcess));
t.IsBackground = true;
theForm.Subscribe(theCreateReport);
t.Start();
Application.Run(theForm);
形式就是形式。 theCreateReport 是我的业务逻辑开始的地方。
Am relatively new to C# and coding in general. I am trying to write a program that has some logic and that also indicates progress with a progressbar. I am starting a thread in Main() that does all my business logic. It has events that are trigerred at points that I need the progress bar udpated.
The Form object subscribes to the business logic events and has thread safe delegates that are invoked to update the progress bars and text labels.
My problem is that, as the Form is started in the main thread, I have to start the business logic thread before Application.Run(). When the first ProgressUpdate event is trigerred, the Form object still does not exist. I guess a hacky way is to add Thread.Sleep(100) in the second thread, but I don't like that. How do I get around this? Am I on a completely incorrect track? (Am I even making sense?)
Form1 theForm = new Form1();
CreateReport theCreateReport = new CreateReport();
Thread t = new Thread(new ThreadStart(theCreateReport.DoProcess));
t.IsBackground = true;
theForm.Subscribe(theCreateReport);
t.Start();
Application.Run(theForm);
theForm is the form. theCreateReport is where my business logic starts.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
您想要使用一个或多个
BackgroundWorker
对象而不是业务逻辑线程。这将为您管理线程,并为您提供一种向主线程提供进度反馈的方法。You want to use one or more
BackgroundWorker
objects instead of your business logic thread. This will manage the threading for you as well as giving you a way to provide progress feedback to the main thread.也许您应该在 OnLoad 事件中开始您的业务逻辑?
Maybe you should start your business logic in OnLoad event?
调用构造函数后(在第一行),表单已经存在 - 只是还不可见。所以你不用担心,当你启动新线程时,一切都会被初始化。
The Form already exists after you invoke the constructor (on the very first line) - it's just not visible yet. So you don't need to worry, everything is initialized when you start the new thread.
在
Main
中,只需创建表单并Application.Run
它。在表单的Load
事件中,启动线程。按照目前的方式做事并没有真正获得任何优势。正如您已经发现的,它会产生时序/顺序问题。
解决问题的最好方法就是从一开始就不存在它们。
In
Main
, just create the form andApplication.Run
it. In theLoad
event of the form, start your thread.You don't really gain any advantage from doing things the way you're currently doing them. And as you've already found, it creates a timing/sequence problem.
The best way to fix problems is to not have them in the first place.
我会使用BackgroundWorker,您仍然可以使用您的事件和委托。这一次,您将结束并触发后台工作人员的“ProgressChanged”和“RunWorkerCompleted”事件。
您的 Form 可以监听这些事件并相应地更新 ProgressBar。
BWorker 可以更好地处理切换到 GUI 线程和异常处理。
您可以在表单加载时初始化BackgroundWorker。
I would use BackgroundWorker and you can still use your events and delegates with it. This time round you will be wrapping up and firing Background Worker's "ProgressChanged" and "RunWorkerCompleted" events.
And you Form can listen to these events and update ProgressBar accordingly.
BWorker handles switching to GUI Thread and Exception Handling better.
You can initialize BackgroundWorker on Form Load.