2011-12-29 71 views
3

我对WPF很新颖。刚开始学习线程。线程的正确方法

这是我的场景: 我用一个名为START的按钮创建了一个程序。当单击开始按钮时,它开始在不同的线程中执行一些复杂的任务。在开始复杂任务之前,它还在另一个STA线程(技术上我不知道我在说什么)创建了中的UI元素。

这里是一个示例代码:

// button click event 
private void button1_Click(object sender, RoutedEventArgs e) 
{ 
    System.Threading.Thread myThread = new System.Threading.Thread(
     () => buttonUpdate("Hello ")); 
    myThread.Start(); 
} 

private void buttonUpdate(string text) 
{ 
    System.Threading.Thread myThread = new System.Threading.Thread(createUI); 
    myThread.SetApartmentState(System.Threading.ApartmentState.STA); 

    // set the current thread to background so that it's existant will totally 
    // depend upon existance of main thread. 
    myThread.IsBackground = true; 
    myThread.Start(); 

    // Please don't read this loop it's just for my entertainment! 
    for (int i = 0; i < 1000; i++) 
    { 
     System.Threading.Thread.Sleep(100); 
     button1.updateControl(new Action(
      () => button1.Content = text + i.ToString())); 
     if (i == 100) 
      break; 
    } 

    // close main window after the value of "i" reaches 100; 
    this.updateControl(new Action(()=>this.Close())); 
} 

// method to create UI in STA thread. This thread will be set to run 
// as background thread. 


private void createUI() 
{ 
    // Create Grids and other UI component here 
} 

上面的代码成功地做什么,我想做的事情。但你认为这是正确的方式吗?到目前为止,我在这里没有任何问题。

编辑:哎呀,我忘了提这个类:

public static class ControlException 
{ 
    public static void updateControl(this Control control, Action code) 
    { 
     if (!control.Dispatcher.CheckAccess()) 
      control.Dispatcher.BeginInvoke(code); 
     else 
      code.Invoke(); 
    } 
} 
+0

如果你真正理解你在说什么,可能会有所帮助。当你了解STA线程的含义时,做一些研究回来。 – 2011-12-29 18:40:41

回答

2

如果您使用的是.NET 4.0,你可能要考虑使用从Task parallel libraryTask类。自从你说你是线程新手之后,请阅读它。使用起来更加灵活。

而且我认为这个链接可能对你很有帮助:

http://www.albahari.com/threading/

+0

我无法使用任务使用UI元素。请参阅:http://stackoverflow.com/questions/8665158/a-very-basic-explanation-for-threading-in-wpf – user995387 2011-12-29 18:02:25

+1

@ user995387 - 您可以使用TaskScheduler.FromCurrentSynchronizationContext方法获取当前同步的TaskScheduler上下文。看看这篇文章:http://stackoverflow.com/questions/5971686/how-to-create-a-task-tpl-running-a-sta-thread – TheBoyan 2011-12-29 18:04:51

+0

谢谢你,这是一个很大的帮助。我会尝试这种方式。 – user995387 2011-12-29 18:08:43

2

似乎没有什么理由使用2个线程。您可以在主线程上执行createUI()。当它变成填充这些控件的时候,这将变得很复杂。

+0

非常感谢您的建议。其实我真的忽视了这一点。 :P – user995387 2011-12-29 18:00:27

+0

顺便说一下,如果我使用tat createUI()来创建flowdocument,那么它会很好吗?我想打印它也将在后台工作 – user995387 2011-12-30 06:57:45

1

只有一个线程可以与UI进行交互。如果您要将控件添加到页面或窗口,那么您必须使用创建页面或窗口的线程。典型的场景是使用线程在后台创建昂贵的数据或对象,然后在回调(在主线程上运行)检索结果并将适当的数据绑定到UI。看看使用BackgroundWorker,因为它会为您处理很多线程细节。 http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx为什么你想在另一个上创建UI对象?

+1

将其添加到流程文档并打印它.... – user995387 2011-12-30 06:40:57

相关问题