加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

C# WPF 多线程使用小结

(2016-08-17 19:51:50)
标签:

wpf

分类: WPF

目的:介绍在WPF下C#多线程的应用,针对从MFC转向C#开发的过程中,两者在多线程中的不同进行。本文不是详细的多线程应用总结,而是强调快速应用,因此,一般的多线程相关概念请自行Google之。

从MFC到C#的多线程一般存在以下疑惑:

1、线程如何创建?

2、线程如何控制?

3、主界面如何更新?


先讲第一个问题:线程如何创建?

C#下创建多线程由类Thread来完成,先看其构造函数:

 

 

  Thread(ParameterizedThreadStart) Initializes a new instance of the Thread class, specifying a delegate that allows an object to be passed to the thread when the thread is started.
  Thread(ThreadStart) Initializes a new instance of the Thread class. 

 

ThreadStart 和 ParameterThreadStart 参数都是委托,所以可以看出委托其实就是方法的抽象,前者用于不带参数的并且无返回值的

方法的抽象后者是带object参数的方法的抽象,大家通过以下简单的方法注意下线程如何调用带参数的方法

实例如下:

public class ThreadStartTest 
    {
        //无参数的构造函数
        Thread thread = new Thread(new ThreadStart(ThreadMethod));
        //带有object参数的构造函数
        Thread thread2 = new Thread(new ParameterizedThreadStart(ThreadMethodWithPara));
        public ThreadStartTest() 
        {
            //启动线程1
            thread.Start();
            //启动线程2
            thread2.Start(new Parameter { paraName="Test" });
        }
        static void ThreadMethod() 
        {
           //....
        }
        static void ThreadMethodWithPara(object o) 
        {
            if (o is Parameter) 
            {
               // (o as Parameter).paraName.............
            }
        }

    }

    public class Parameter 
    {
        public string paraName { get; set; }
    }

不带参数的方法似乎很简单的能被调用,只要通过第一个构造函数便行,对于带参数的方法,大家注意下参数是如何传入线程所调用的方法,当启动线程时,参数通过thread.Start方法传入,于是我们便成功启动了thread线程

第二个问题:线程如何控制?

Thread.start();Thread.sleep();Thread.... 等

第三个问题:主界面如何更新?

这个问题是学习过程中的主要问题点。下面具体谈谈。

  CLR下每个线程创建的控件只能由所创建的线程控制,其他线程进行修改将会出错。

WPF下界面由UI线程创建并控制,从线程安全的角度来说,其他线程要更新UI界面,都需要通过UI线程来更新。如何进行呢?通过委托,即我(另一线程)要更新UI线程的控件,我不能自己修改,我得委托主人家去修改。背后应该也是通过消息的机制来完成的。

 this.Dispatcher.BeginInvoke((Action)delegate()
            {
                hWindowControl.HalconWindow.DispObj(hImage);
            });


下面是一个完整的例子,通过多线程控制大恒相机进行采集图像并显示,基于Halcon进行显示。需安装Halcon10及以上版本,同时引用其控件

CODE:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using HalconDotNet;
using System.Threading;
using System.Windows.Threading;
using USBCamera;
using USBCameraAPI = USBCamera.API;
using USBCameraSample;


namespace multiThread_snap
{
    ///
    /// Interaction logic for MainWindow.xaml
    ///
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            m_Camera.Initialize();
            hImage = new HImage();
          
        }
        private void snap_Click(object sender, RoutedEventArgs e)
        {
          ThreadStart dethreadst = new ThreadStart(Snap);
          Thread thread= new Thread(dethreadst);
          thread.Start(); 


        }
        private USBCameraSample.USBCameraSample m_Camera = new USBCameraSample.USBCameraSample();


        private void Window_Closed(object sender, EventArgs e)
        {
            m_Camera.Release();
        }


        private void Snap()
        {
            IntPtr[] buffers = new IntPtr[1];
            buffers[0] = m_Camera.GetRawBuffer();


            HVSTATUS status = USBCameraAPI.HVSnapShot(m_Camera.GetHandle(), buffers, 1);
            hWindowControl.HalconWindow.SetPart(0, 0, 2592, 1944);
            hImage.GenImage1("byte", 2592, 1944, m_Camera.GetRawBuffer());
            this.Dispatcher.BeginInvoke((Action)delegate()
            {
                hWindowControl.HalconWindow.DispObj(hImage);
            });
          
        }
        private HImage hImage;
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {           
        }
        private void redKey_Click(object sender, RoutedEventArgs e)
        {
            disp.Fill = Brushes.Red;
        }
        private void greenKey_Click(object sender, RoutedEventArgs e)
        {
            disp.Fill = Brushes.Green;
        }
    }
}//namespace


XAML:


        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="768" Width="1024"
    xmlns:my="clr-namespace:HalconDotNet;assembly=halcondotnet"
    WindowStartupLocation="CenterScreen"
    Closed="Window_Closed"
    Loaded="Window_Loaded">
   
       

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有