ホームページ  >  記事  >  バックエンド開発  >  C# マルチスレッドパラメータの受け渡し

C# マルチスレッドパラメータの受け渡し

黄舟
黄舟オリジナル
2017-02-17 10:51:301680ブラウズ

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. 戻った方が良い場合 価値に関しては、どのようにエレガントに書くべきですか?匿名関数 C# マルチスレッドパラメータの受け渡し

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) を参照してください。


声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。