需要帮助在C#中实现multithreading

我正在创建一个应用程序,由于某种原因,当我点击按钮时,我必须启动一个新表单,同时在google文档中创建一个新文档。 我已经成功实现了上述function,但是当应用程序忙于在google docs上创建新文档时,新加载的表单的UI会冻结。 我在某处读到,如果我使用multithreading,这可以避免。 所以现在我想问我应该创建两个线程,其中一个我应该放置代码来创建新表单,另一个我应该放置代码在google doc中创建一个文档。 或者我应该在线程上创建我应该放置代码来创建新的google doc并让新表单创建代码在主进程中? 另外,在已经编写的代码中实现线程的最简单方法是什么? 如果可能的话,请提供一些参考阅读材料。

你实际上有很多选择。

(1) BackgroundWorker。 如果你真的想要在WinForms中进行异步工作的最简单的编程模型,那就是这个。 它通常用于执行某些异步任务并报告进度,但如果您不需要,则不必报告进度。

(2) 基于事件的异步模式。 如果您想制作一个完整的组件来执行某些异步任务,完全控制报告进度和您自己的自定义事件,那么这是一种方法。 这也有助于您理解线程,而不是BackgroundWorker。 因为我是一个视觉人, 所以我创建了一个完整的video演示文稿,介绍如何使用WinForms进行此操作 。

(3) 任务并行库。 您可以将TPL与WinForms一起使用,我在这里写了一篇非常详细的博客文章,介绍如何做到这一点 。

(4) 异步和等待 。 请注意,这需要.NET 4.5,C#5.0和C#5.0编译器仅包含在Visual Studio 11中,Visual Studio 11目前仅在BETA中。 但是,我还有一篇关于如何做到这一点的完整博客文章 。

(5) 带线程的ISynchronizedInvoke。 这是另一种选择, 我也有一个完整的博客 。

这取决于您选择哪种方法。 我的建议是简要介绍每一个,并根据主题对您的感受,或者哪种方法最符合您的要求,选择一种方法。

你可以使用许多技术来做你想要的但我会推荐任务并行库(TPL)(或BackgroundWorker )。

创建/启动新表单的开销很小(在大多数情况下),因此在我看来,您应该在UI线程上启动表单,并在后台线程上创建Google Doc。 所以使用TPL你会有类似的东西(非常基本的例子)

 // In click event. MyForm newForm = new MyForm(); newForm.Show(); Task googleDocTask = Task.Factory.StartNew(() => { // Do your stuff with Google Docs. // Note you cannot access the UI thread from within this delegate. }); 

有关C#中线程的详细讨论,请参阅Joseph Albahari关于线程的页面 。

有关TPL的更多信息和相当完整的介绍,请参见此处 。

我希望这有帮助。

只需创建一个线程。 我建议使用BackgroundWorker。 他们非常直接。

把它放在你class级的顶端:

 private BackgroundWorker googleDocWorker = new BackgroundWorker(); 

把它放在你的构造函数中:

 googleDocWorker.DoWork += new DoWorkEventHandler(googleDocWorker_DoWork); googleDocWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(googleDocWorker_RunWorkerCompleted); 

把这些方法放在你的class级:

 void googleDocWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { // You can use this to alert you that the google doc is created. } void googleDocWorker_DoWork(object sender, DoWorkEventArgs e) { // Create google doc here. } 

调用此方法开始创建google doc:

 googleDocWorker.RunWorkerAsync(); 

现在,如果您需要将一些数据传递给BackgroundWorker,您可以传递任何您想要的内容。 您可以使用对象数组传入字符串,甚至是不同类型的多个对象。 这是一个发送多个对象的示例:

 googleDocWorker.RunWorkerAsync(new object[] { "doc name", contents }); 

现在,这意味着它们必须在_DoWork方法中处理:

 void googleDocWorker_DoWork(object sender, DoWorkEventArgs e) { // Create google doc here. object[] args = (object[])e.Argument; String docName = (string)args[0]; SomeClass contents = (SomeClass)args[1]; } 

假设在创建文档之后,您希望将URL发送回刚刚创建的文档,您只需将其传递回_DoWork方法的_RunWorkerCompleted方法:

 void googleDocWorker_DoWork(object sender, DoWorkEventArgs e) { // Create google doc here. ... e.Result = myURL; } 

在RunWorkerCompleted方法中获取URL后,它与DoWork方法几乎相同。

 void googleDocWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { // You can use this to alert you that the google doc is created. String docURL = (String)e.Result; } 

希望有所帮助! (:

恕我直言。 你应该只创建一个你将制作谷歌文档的线程(所以你将有两个线程)。

最简单的方法是使用BackgroundWorker或使用ThreadPool。 如果您的主UI在其他任务完成时不关心,则Threadpool会更简单。