1. エンティティ クラスを通過します (複数のパラメーターを渡して戻り値を取得できます)。デモは次のとおりです:
スレッド内で呼び出す必要がある関数:
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); } } }
Call:
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 が false の場合、IsBack Ground の問題に注意する必要があります、Windows プログラムが終了するとき、スレッドは自動的に終了しません。つまり、アプリケーションは実際には終了していません。
MSDN 推奨事項: マルチスレッド メソッド呼び出しのパラメーターを提供する最良の方法は、ターゲット メソッドをクラスでラップし、新しいスレッドのパラメーターとして使用されるクラスのフィールドを定義することです。
このアプローチの利点は、新しいスレッドを開始したいときはいつでも、独自のパラメーターを使用してクラスの新しいインスタンスを作成できることです。
ThreadStart クラスの関数
には戻り値もパラメータもありません
2. 非同期呼び出しのパラメータと戻り値
は完璧に解決できます パラメータと戻り値その方法は、非同期呼び出しを使用することです。 Thread と比較した場合、非同期呼び出しの最大の欠点の 1 つは、優先順位を制御できないことです。
具体的なコードは次のとおりです:
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); }
小さなメモ:
この方法で生成された新しいスレッドは、背景 (背景)、優先度は通常です
3. BackgroundWorker を使用する
マルチスレッド値を返す最も簡単な方法は、BackgroundWorker コンポーネントを使用してスレッドを管理し、イベントを発生させることです。タスクが完了したら、イベント ハンドラーで結果を処理します。
注意:
BackgroundWorker コンポーネントは、データベース トランザクションやファイルのダウンロードなど、時間のかかる非同期操作を実行するために使用されます。
BackgroundWorker インスタンスをアプリケーションに追加します。VS を使用している場合は、ツールからアプリケーションに直接ドラッグできます:
BackgroundWorker backgroundWorker1 = new BackgroundWorker();
バックグラウンドで動作を開始するには、RunWorkerAsync を呼び出す必要があります。 BackgroundWorker の () メソッド。このメソッドが呼び出されると、BackgroundWorker は DoWork イベントをトリガーしてバックグラウンド操作の実行を開始します。DoWork イベントのコードが別のスレッドで実行されます。
バックグラウンド操作が完了すると、完了したかキャンセルされたかに関係なく、RunWorkerCompleted イベントがトリガーされ、バックグラウンド操作の完了結果をユーザーにフィードバックできます。
さらに、RunWorkerCompletedEventArgs インスタンスの Canceled プロパティを使用して、バックグラウンド操作が Cancel 操作によって終了するかどうかを判断できます。
具体的なデモは次のとおりです:
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()); } } }
デモ コードは MSDN から取得しています: クリックしてリンクを開きます
参考記事:を開くにはlink
4. 戻った方が良い場合 価値に関しては、どのようにエレガントに書くべきですか?匿名関数
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# マルチスレッド パラメーターの受け渡しの内容です。さらに関連する内容については、PHP 中国語 Web サイト (www.php.cn) を参照してください。