2011-04-05 105 views
0

对于C#和编码来说,这是一个相对较新的概念。我正在尝试编写一个具有某些逻辑的程序,并且还指出了进度条的进度。我正在Main()中启动一个线程,它执行我所有的业务逻辑。它有一些事件在我需要进度条的地方被激怒。C#Winform多线程序列

Form对象订阅业务逻辑事件并具有线程安全委托,它们被调用以更新进度条和文本标签。

我的问题是,因为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); 

theForm是表单。创建报告是我的业务逻辑开始的地方。

回答

0

在调用构造函数(在第一行)之后,窗体已经存在 - 它只是不可见。所以你不用担心,当你开始新线程时,所有的东西都会被初始化。

+0

这就是为什么我将构造函数从默认的VC#S项目中分离出来的原因。它似乎并没有工作。给我一个错误,说在创建对象之前我不应该使用Invoke/BeginInvoke。如果我将一个try catch块放入空捕捉块中,它确实有效,但感觉像是一个黑客。这可能只是我很挑剔。 – whatsinaname 2011-04-06 00:10:56

+0

这是一个黑客。 .Net中基于表单的应用程序基本上是围绕主表单的概念构建的。没有理由与之抗衡,因为您的项目已经使用了主表单。 – MusiGenesis 2011-04-06 00:27:59

+0

将此标记为答案,因为正如波马提到的那样,表单已经存在。该错误在我的代码的不同部分。谢谢。 – whatsinaname 2011-04-18 14:03:14

1

也许你应该在OnLoad事件中启动你的业务逻辑?

4

要使用一个或多个BackgroundWorker对象而不是业务逻辑线程。这将为您管理线程,并为您提供向主线程提供进度反馈的方法。

+0

与从Form1()方法中启动我的线程有什么不同?我已经有我的处理人员和代表。从Form中开始/执行所有业务逻辑是否是一种很好的编程实践?就像我刚才提到的那样,这里是一个完整的新手。谢谢。 – whatsinaname 2011-04-06 00:08:26

+0

如果你已经有一些工作,然后通过一切手段使用它。 BackgroundWorker只是为您提供一种简单的方法,将离散任务抛出到另一个线程,并在稍后获得结果,而无需管理自己的线程。 – geofftnz 2011-04-06 01:39:03

0

Main,只需创建表格和Application.Run它。在表单的Load事件中,启动您的线程。

你不会像现在那样做事情而获得任何优势。正如你已经发现的那样,它会造成时序/序列问题。

解决问题的最佳方法是不要让他们摆在首位。

+0

我被告知完全分离GUI和业务逻辑是一种很好的做法。 (而不是从GUI方法中启动业务逻辑线程)。但是,这确实来自我与之合作的Java开发人员。所以我不知道它是否适用于C#编码的情况。 – whatsinaname 2011-04-06 00:03:53

+0

GUI和业务逻辑的分离与代码的组织方式有关,而不是运行不同对象的线程。一般来说,多线程应用程序的可靠性低于单线程应用程序,因为通过代码的路径受到线程调度程序的控制,因此难以预测。有合理的理由需要多线程的固有风险(如果你知道自己在做什么,它就可能安全地做到这一点),但符合三层正统的标准确实不是其中之一。 – MusiGenesis 2011-04-06 00:21:38

0

我会使用BackgroundWorker,你仍然可以使用它的事件和委托。这一次你将会结束并解雇Background Worker的“ProgressChanged”和“RunWorkerCompleted”事件。

而你表单可以监听这些事件并相应地更新ProgressBar。

BWorker更好地处理切换到GUI线程和异常处理。

您可以在Form Load上初始化BackgroundWorker。