须要在线程中挪用的函数:
namespace ThreadParameterDemo { public class FunctionClass { public static string TestFunction(string name, int age) { //内部处置惩罚省略 return name + " 的岁数是:" + age; } } }
经由过程实体来来封装:
namespace ThreadParameterDemo { /// <summary> /// 过渡类 /// </summary> public class TransitionalClass { private string name = string.Empty; private int age; public string acceptResults = string.Empty; public TransitionalClass(string name, int age) { this.name = name; this.age = age; } public void TestFunction() { acceptResults = FunctionClass.TestFunction(this.name, this.age); } } }
挪用:
private void Form1_Load(object sender, EventArgs e) { //实例化ThreadWithState类,为线程供应参数 TransitionalClass tc = new TransitionalClass(" Jack", 42); // 建立实行使命的线程,并实行 Thread t = new Thread(new ThreadStart(tc.TestFunction)); t.Start(); //猎取返回值,经由过程 tc.acceptResults; }
小注:
必需注重IsBackground的题目,假如IsBackground为false的,则Windows顺序在退出的时刻,不会为你自动退出该线程。也就是实际上你的应用顺序未完毕。
MSDN引荐:多线程要领挪用供应参数的最好方法是将目的要领包裹在类中,并为该类定义字段,这些字段将被用作新线程的参数。
这类要领的长处是,任何时刻想要启动新线程,都能够建立类的新实例,该实例带有本身的参数。
BackgroundWorker 类
ThreadStart中的函数是没有返回值和参数的
2、异步挪用中的参数和返回值
能圆满处理参数和返回值的是运用异步挪用的体式格局。异步挪用和Thread比拟,一个最大的劣势是不能掌握其优先级。
详细代码以下:
public delegate string delegateFunction(string name,int age);//托付 delegateFunction df; private void Form1_Load(object sender, EventArgs e) { //指向须要挪用的要领 df = new delegateFunction(FunctionClass.TestFunction); string name = "my name";//输入参数 int age = 19; IAsyncResult result = df.BeginInvoke(name,age, null, null); string myResult = df.EndInvoke(result);//用于吸收返回值 MessageBox.Show(myResult); }
简化:
public Func<string, int, string> df;//托付 private void Form1_Load(object sender, EventArgs e) { //指向须要挪用的要领 df += FunctionClass.TestFunction; string name = "my name";//输入参数 int age = 19; IAsyncResult result = df.BeginInvoke(name, age, null, null); string myResult = df.EndInvoke(result);//用于吸收返回值 MessageBox.Show(myResult); }
小注:
经由过程这类体式格局生成新线程是运转在背景的(background),优先级为normal
3、运用 BackgroundWorker
多线程返回值最简朴要领是:运用 BackgroundWorker 组件来治理线程,在使命完成时激发事宜,然后用事宜处置惩罚顺序处置惩罚效果。
小注:
BackgroundWorker 组件用来实行诸如数据库事件、文件下载等耗时的异步操纵。
在应用顺序中增加一个BackgroundWorker实例,假如用的是VS,能够从东西上直接拖到应用顺序:
BackgroundWorker backgroundWorker1 = new BackgroundWorker();
为了最先在背景操纵,必需挪用BackgroundWorker的RunWorkerAsync()要领,当挪用此方时,BackgroundWorker 经由过程触发DoWork 事宜,最先实行背景操纵,DoWork 事宜的代码是在另一个线程里实行的。
当背景操纵完成今后,无论是completed 照样cancelled,则RunWorkerCompleted 事宜被触发,经由过程此要领能够将背景操纵的完成效果反馈给用户。
别的,经由过程RunWorkerCompletedEventArgs实例的Cancelled 属性,以推断是不是是Cancel操纵使得背景操纵停止。
详细demo以下:
using System; using System.Windows.Forms; namespace WindowsFormsApplication1 { public partial class Form2 : Form { public Form2() { InitializeComponent(); } private void Form2_Load(object sender, EventArgs e) { //TransitionalClass tc = new TransitionalClass("xiaoming", 10); //ThreadPool.QueueUserWorkItem(new WaitCallback(TransitionalClass.TestFunction), tc); } private void button1_Click(object sender, EventArgs e) { this.TestArea2(); } private System.ComponentModel.BackgroundWorker BackgroundWorker1 = new System.ComponentModel.BackgroundWorker(); private void TestArea2() { InitializeBackgroundWorker(); AreaClass2 AreaObject2 = new AreaClass2(); AreaObject2.Base = 30; AreaObject2.Height = 40; // Start the asynchronous operation. BackgroundWorker1.RunWorkerAsync(AreaObject2); } private void InitializeBackgroundWorker() { // Attach event handlers to the BackgroundWorker object. BackgroundWorker1.DoWork += new System.ComponentModel.DoWorkEventHandler(BackgroundWorker1_DoWork); BackgroundWorker1.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(BackgroundWorker1_RunWorkerCompleted); } private void BackgroundWorker1_DoWork( object sender, System.ComponentModel.DoWorkEventArgs e) { //在实行DoWork 事宜时,DoWorkEventArgs 实例的Result 属性,返回值到用户;在RunWorkerCompleted 事宜里,RunWorkerCompletedEventArgs 实例的Result 属性吸收值; AreaClass2 AreaObject2 = (AreaClass2)e.Argument; // Return the value through the Result property. e.Result = AreaObject2.CalcArea(); } private void BackgroundWorker1_RunWorkerCompleted( object sender, System.ComponentModel.RunWorkerCompletedEventArgs e) { // Access the result through the Result property. double Area = (double)e.Result; MessageBox.Show("The area is: " + Area.ToString()); } } }
demo代码来自MSDN:点击翻开链接
参考文章:点击翻开链接
FunctionClass类新增,测试函数以下:
public static void TestFunction2(string name, int age) { //内部处置惩罚省略 }
挪用以下:
private void Form1_Load(object sender, EventArgs e) { Thread t1 = new Thread(new ThreadStart(delegate { FunctionClass.TestFunction2("eee", 5); })); t1.Start(); }
小注:
假如经由过程WCF来挪用的话,应当把起线程的函数放到服务端,假如放到客户端,很轻易由于WCF客户端的时候限定,形成形成主顺序的莫名崩溃。
崩溃的缘由主如果客户端wcf相应时候是有限定。
以上就是C# 多线程参数通报的内容,更多相关内容请关注ki4网(www.ki4.cn)!