【问题标题】:correct method of threading正确的穿线方法
【发布时间】:2012-01-30 01:45:21
【问题描述】:

我对 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();
    }
}

【问题讨论】:

  • 如果您真正理解您在说什么,可能会有所帮助。了解 STA 线程的含义后,再做一些研究。

标签: c# .net wpf multithreading optimization


【解决方案1】:

如果您使用的是 .NET 4.0,您可能需要考虑使用 Task parallel library 中的 Task 类。阅读它,因为您说您是线程新手。使用起来更加灵活。

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

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

【讨论】:

【解决方案2】:

似乎没有充分的理由使用 2 个线程。

您应该能够在主线程上执行createUI()。当需要填充这些控件时,这将变得足够复杂。

【讨论】:

  • 非常感谢您的建议。事实上,我真的忽略了这一点。 :P
  • 顺便说一句,如果我使用 tat createUI() 创建流文档会更好吗?我想打印它也可以在后台工作
【解决方案3】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-01-15
    • 2018-05-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-06
    • 2022-01-23
    相关资源
    最近更新 更多