[C#参考]主线程和子线程之间的参数传递

几个进程在大多数情况下要包含很多的子线程,那么他们之间免不了的要互相传递很多的参数,那么参数怎么传递的呢?


主线程向子线程传递参数的方法



第一种方法:Thraed类有一个带参数的委托类型的重载形式,这个委托的定义如下:

public delegate void ParameterizedThreadStart(Object obj)

这个Thread类的构造方法的定义如下:

public Thread(ParameterizedThreadStart start);

下面的代码使用了这个带参数的委托向线程传递一个字符串参数:

public static void myStaticParamThreadMethod(Object obj)
{
    Console.WriteLine(obj);
}
 
static void Main(string[] args)
{
    Thread thread = new Thread(myStaticParamThreadMethod);
    thread.Start("通过委托的参数传值");
}

注意这种形式,委托就是Thread要执行的方法,这个委托有一个类的实例对象作为参数。然后在Thread的Start()方法中把这个对象传进去。

如果使用了不带参数的委托,当然也能很正常的启动线程,别学傻了。

第二种方法:定义一个类来传递参数

class Program
    {
        static void Main(string[] args)
        {
            MyData myData = new MyData("abcd", 1234);
            Thread thread = new Thread(myData.ThreadMethod);
            thread.Start();

            Console.ReadKey();
        }
    }//class

    //定义一个类传递参数
    public class MyData
    {
        private string d1;
        private int d2;

        public MyData(string d1, int d2)
        {
            this.d1 = d1;
            this.d2 = d2;
        }

        public void ThreadMethod()
        {
            Console.WriteLine(d1);
            Console.WriteLine(d2);
        }
    }//class

这种方法的特点是:子线程的执行入口是在另一个类中,这样正好可以借助这个类的成员函数,给子线程传参。

第三种方法:定义一个新的线程类,让所有的子线程类都继承自这个类

abstract class MyThread
{
    Thread thread = null;
 
    abstract public void run();
 
    public void Start()
    {
        if (thread == null)
        {
            thread = new Thread(run);
            thread.Start();
        }
    }
}
class Utility : MyThread

{
    private string d1;
    private int d2;
 
    public override void run()
    {
        Console.WriteLine(d1);
        Console.WriteLine(d2);
    }
 
}//class

其实上面的两种方法的原理是一样的,这是一个面向数据,一个面向线程。


子线程向主线程传递参数



这里看到是传递参数,也就是说子线程要调用主线程的一个方法,然后把参数传递给主线程的那个方法。说一下方法是前面已经讲过的Invoke和BeginInvoke,但是那时调用主线程的方法并没有传递参数,今天看一下带参数的调用主线程的指定方法。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;

namespace WindowsFormsApplication3
{
    public partial class Form1 : Form
    {
        private int count = 0;

        private delegate void DoWorkUIThreadDelegate();
        public Form1()
        {
            InitializeComponent();
        }

        private void btnStart_Click(object sender, EventArgs e)
        {
            Thread thread = new Thread(ThreadMethod);
            thread.IsBackground = true;
            thread.Start();
        }

        private void ThreadMethod()
        {
            while (true)
            {
                //lblResult.Text = DateTime.Now.ToString();
                //这句话不能直接调用,因为子线程不能直接调用UI线程中的控件
                if (this.InvokeRequired)
                {
                    this.BeginInvoke(new DoWorkUIThreadDelegate(DoWorkUIThread), null);
                }
                else
                {
                    DoWorkUIThread();
                }

                //子线程还是可以访问UI线程的普通变量的,只是不能访问控件
                //因为普通变量是属于整个类的,属于整个进程的,各个线程时共享的
                //对访问共享的数据,加一个lock的锁更加的好
                count++;
                Thread.Sleep(1000);
            }

        }

        private void DoWorkUIThread()
        {
            txtTime.Text = DateTime.Now.ToString() + " " + count;
        }
    }
}

上面的这种情况似乎用不着子线程给UI线程返回数据,反正子线程可以访问主线程的成员变量。但是另一种情况来了,当子线程不再UI线程所在的类的时候,也就是说子线程在一个工具类中,UI类new出来一个工具类完成一定的工作,UI类可以初始化工具类,但是工具类完成了一定任务后怎么通知UI类呢?现在有这种假设:

UI类要Socket连接网络,现在有一个SocketUtil工具可以完成这项任务,所以UI类就New出来一个SocketUtil,然后调用指定的函数,把IP和Port传递进去。在完成了一些任务以后,SocketUtil要反馈一些信息给UI类。让UI类显示反馈的信息。现在面临两个问题:

1. UI类怎么知道SocketUtil完成了这项任务,然后取显示数据呢?

2. UI类即使知道了什么时候显示信息,那么要显示的内容,UI类怎么知道是什么呢?

第一个问题的解决方法就是事件,利用事件就能在SocketUtil完成一些任务之后,通知UI类接下来怎么做。

第二个问题就是利用Invoke让子线程给主线程调用主线程的函数完成任务的时候,给一些参数。

这里就直接在同一个类中展示一下:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;

namespace WindowsFormsApplication3
{
    public partial class Form1 : Form
    {
        private int count = 0;

        private delegate void DoWorkUIThreadDelegate(string name, int id);
        public Form1()
        {
            InitializeComponent();
        }

        private void btnStart_Click(object sender, EventArgs e)
        {
            Thread thread = new Thread(ThreadMethod);
            thread.IsBackground = true;
            thread.Start();
        }

        private void ThreadMethod()
        {
            string strName = "stemon";
            int ID = 1;

            while (true)
            {
                //lblResult.Text = DateTime.Now.ToString();
                //这句话不能直接调用,因为子线程不能直接调用UI线程中的控件
                if (this.InvokeRequired)
                {
                    object[] myArray = new object[2];
                    //类型的装箱是自动的
                    //类型的拆箱要强制转换
                    myArray[0] = strName;
                    myArray[1] = ID;

                    this.BeginInvoke(new DoWorkUIThreadDelegate(DoWorkUIThread), myArray);
                }
                else
                {
                    //DoWorkUIThread(strName, ID);
                }

                //子线程还是可以访问UI线程的普通变量的,只是不能访问控件
                //因为普通变量是属于整个类的,属于整个进程的,各个线程时共享的
                //对访问共享的数据,加一个lock的锁更加的好
                count++;
                Thread.Sleep(1000);
            }

        }

        private void DoWorkUIThread(string name, int id)
        {
            txtTime.Text = name + " " + id + " " + DateTime.Now.ToString() + " " + count;
        }
    }
}

这个方法是这样操作的,BeginInvoke可以传递一个数组,这个数组是boject类型的,这样就可以把所有的参数都装箱成object类型的,弄成一个object类型的数组,然后到调用方在拆封就可以了。

时间: 2024-11-07 18:30:31

[C#参考]主线程和子线程之间的参数传递的相关文章

Android 使用handler实现线程间发送消息 (主线程 与 子线程之间)、(子线程 与 子线程之间)

keyword:Android 使用handler实现线程间发送消息 (主线程 与 子线程之间).(子线程 与 子线程之间) 相信大家平时都有使用到异步线程往主线程(UI线程)发送消息的情况. 本文主要研究Handler的消息发送. 包含主线程往子线程发送消息,子线程之间互相发送消息. 一.主线程向子线程发送消息. 实现过程比較简单: 主线程发送消息到异步线程.异步线程接收到消息后在再发送一条消息给主线程. 1. 初始化主线程的Handler,用来接收子线程的消息. 2. 启动异步线程.在异步线

(转)C#/.NET主线程与子线程之间的关系

一般 一个应用程序就对应一个进程,一个进程可有一个或多个线程,而一般有一个主线程. 有的博客上说“至少一个主线程”,这一说法持有怀疑         主线程与子线程之间的关系         **默认情况,在新开启一个子线程的时候,他是前台线程,只有,将线程的IsBackground属性设为true;他才是后台线程         *当子线程是前台线程,则主线程结束并不影响其他线程的执行,只有所有前台线程都结束,程序结束         *当子线程是后台线程,则主线程的结束,会导致子线程的强迫结

Handler详解系列(四)——利用Handler在主线程与子线程之间互发消息

MainActivity如下: package cc.c; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.widget.TextView; /** * Demo描述: * * 示例步骤如下: * 1 子线程给子线程本身发送消息 * 2 收到1的消

Handler具体解释系列(四)——利用Handler在主线程与子线程之间互发消息

MainActivity例如以下: package cc.c; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.widget.TextView; /** * Demo描写叙述: * * 演示样例过程例如以下: * 1 子线程给子线程本身发送消息 *

android 主线程和子线程之间的消息传递

从主线程发送消息到子线程(准确地说应该是非UI线程) package com.zhuozhuo;import android.app.Activity;import android.os.Bundle;import android.os.Handler;import android.os.Looper;import android.os.Message;import android.util.Log;import android.view.View;import android.view.Vie

在C#中主线程和子线程如何实现互相传递数据

在C#中主线程和子线程如何实现互相传递数据 老帅 在C#中创建线程Thread时,可以有多种方法,而主线程和子线程之间又如何实现互相传递数据,每种创建方法传递参数的效果是不同的,逐一看一下:  一.不带参数创建Thread 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 using System;  using System.Collections.Generic;  using System.Text;  using Sy

在C#中主线程和子线程如何实现互相传递数据(转)

在C#中创建线程Thread时,可以有多种方法,而主线程和子线程之间又如何实现互相传递数据,每种创建方法传递参数的效果是不同的,逐一看一下: 一.不带参数创建Thread 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 using System;  using System.Collections.Generic;  using System.Text;  using System.Threading;  namespace

C++拾遗--多线程:主线程与子线程的同步

C++拾遗--多线程:主线程与子线程的同步 前言 在多线程编程时,有时是需要要求主线程与子线程同步的. 正文 程序演示 下面的一个例子,演示了主线程与子线程之间的同步问题. 程序描述: 在主线程中,有一整型变量count,初始化为0.主线程把count的地址传递给开启的子线程,子线程打印获取的值,随后主线程递增count的值,再次开启另一个子线程,传递count的地址-- #include <stdio.h> #include <stdlib.h> #include <pro

Android笔记(三十二) Android中线程之间的通信(四)主线程给子线程发送消息

之前的例子都是我们在子线程(WorkerThread)当中处理并发送消息,然后在主线程(UI线程)中获取消息并修改UI,那么可以不可以在由主线程发送消息,子线程接收呢?我们按照之前的思路写一下代码: package cn.lixyz.handlertest; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.Message; import andr