2012-04-19 89 views
1

我正在一个应用程序中,当我点击一个按钮,我要开始新的形式,并在同一时间创建的谷歌文档的新文档的一些原因。 我已经成功实现了上述功能,但是当应用程序忙于在Google文档中创建新文档时,新加载的表单的UI会冻结。 我在某处读到,如果使用多线程,可以避免这种情况。 所以现在我想问我应该创建两个线程,在其中一个我应该放置代码来创建新的窗体,另一个我应该放置代码来创建一个文档在谷歌文档。 或者我应该创建一个线程,在这个线程中我应该放置代码来创建新的Google文档,并让新的表单创建代码在主进程中? 另外什么是在一个已经写好的代码中实现线程的最简单的方法?如有可能,请提供一些参考阅读材料。需要帮助实现多线程在C#中

+1

您的第一选择应该是与Google会谈的[Backgroundworker](http://msdn.microsoft.com/en-us/library/cc221403%28VS.95%29.aspx)。 – 2012-04-19 08:15:05

+0

@HenkHolterman - 我会去那。只需在新窗体上放置一个代码,并将所有代码放在那里。它可以在新窗体初始化时运行。任务完成。 – 2012-04-19 08:37:06

回答

0

恕我直言。你应该只创建一个线程,你可以创建谷歌文档(所以你会有两个线程)。

+0

如果你想创建线程的代码在哪里将创建谷歌文档,我需要你的函数属性(返回值,params) – Likurg 2012-04-19 08:20:27

2

你可以使用一些技巧做你问什么,但我会建议任务并行库(TPL)(或BackgroundWorker)这一点。

创建/启动新的形式具有非常小的开销(在大多数情况下),所以在我看来,你应该启动UI线程上的形式,并在后台线程创建谷歌文档。因此,使用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's page on threading

欲了解更多信息和比较完整地介绍了TPL看到here

我希望这会有所帮助。

0

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

2

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

抛出这个在您的类的顶部:

private BackgroundWorker googleDocWorker = new BackgroundWorker(); 

在构造函数将这个:

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

把这些方法在你的类:

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. 
} 

调用此开始创建谷歌文档:

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,这是刚刚创建的文档,你只传递回_RunWorkerCompleted方法从_DoWork方法:

void googleDocWorker_DoWork(object sender, DoWorkEventArgs e) 
{ 
    // Create google doc here. 

    ... 

    e.Result = myURL; 
} 

获取网址,一旦你在RunWorkerComplete是d方法,它几乎与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; 
} 

希望有帮助! (:

6

你确实有很多选择

(1)BackgroundWorker的如果你真的想在WinForms的异步工作的最简单的编程模型,这将是这个它通常用来做一些。异步任务和报告进度,但是如果你不需要,你不必报告进度。

(2)基于事件的异步模式如果你想做一个完整的组件,异步任务,完全控制报告进度和您自己的自定义事件,那么这是一种方法他还可以帮助您理解线程而不是BackgroundWorker。因为我是一个视觉的人,I created a full video presentation on how to do just this with WinForms

(3)任务并行库。你可以使用WinForms的TPL,并且我写了一个very detailed blog post on how to do just that here

(4)异步和等待。请注意,这需要仅包含在Visual Studio 11中的.NET 4.5,C#5.0和C#5.0编译器,Visual Studio 11现在只能在BETA中使用。 However, I also have a full blog post on how to do just this

(5)ISynchronizedInvoke with Threads。这是另一个选项,其中I also have a full blog about

这真的取决于你选择哪种方法。我的建议是对每种方法进行简要介绍,然后根据主体对您的感受程度来选择一种方法,或者采用哪种方法可以最好地满足您的要求。