代码之家  ›  专栏  ›  技术社区  ›  Nick_F

如何避免线程应用程序中的全局变量

  •  0
  • Nick_F  · 技术社区  · 6 年前

    我制作了一个简单的应用程序,它使用后台工作人员调用执行缓慢的任务。我希望能够向slow函数传递一些参数,并在任务完成时获得结果。我可以通过使用全局变量a、b和product来实现这一点。 有没有更好的方法将参数传递给slow函数并返回结果?

    using System;
    using System.Collections.Generic;
    using System.Drawing;
    using System.Windows.Forms;
    
    using System.Threading;
    using System.ComponentModel; // for BackgroundWorker
    
    namespace ThreadsDelegate
    {
        /// <summary>
        /// Description of MainForm.
        /// </summary>
        public partial class MainForm : Form
        {
            Random rnd = new Random();
            int a; // will be used by the slow task
            int b; // will be used by the slow task
            string product = null; // we get back the result of the slow task
            int i = 0; // counter
    
            public MainForm()
            {
                InitializeComponent();
                listBox1.Items.Add("Starting a long task of multiplication, that takes a few seconds.");
                listBox1.Items.Add("We can still use the form interface for other activities, such as generating random numbers...");
                listBox1.Items.Add("We can call the multiplication function multiple times by pressing the button and it will return multiple answers");
                listBox1.Items.Add("When the multiplication task is complete, the results will be displayed");
            }
    
            void BtnRandomClick(object sender, EventArgs e)
            {
                int number = rnd.Next(0, 1000); 
                tbRandomNumber.Text = number.ToString();
            }
    
            void BtnSlowTaskClick(object sender, EventArgs e)
            {
                a = rnd.Next(1, 9);  // we use global variables to pass data to slow function
                b = rnd.Next(11, 22); // we use global variables to pass data to slow function
    
                BackgroundWorker bg = new BackgroundWorker();
                bg.DoWork += new DoWorkEventHandler(SlowMultiply);
                bg.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bg_RunWorkerCompleted);
                bg.RunWorkerAsync();
            }
    
            void bg_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
            {
                listBox1.Items.Add((++i) + ". Result of multiplication: " + product);
            }
    
            void SlowMultiply(object sender, DoWorkEventArgs e)
            {
                int prod = a * b;
    
                for (int i = 1; i <= 5; i++)
                {
                    Thread.Sleep(500);
                }
    
                product = prod.ToString(); // update the global variable
            }       
        }
    }
    
    1 回复  |  直到 6 年前
        1
  •  1
  •   Tom F    6 年前

    您可以通过如下后台工作程序发送参数:

    int a =  rnd.Next(1, 9);
    int b =  rnd.Next(11, 22);
    var data = new Tuple<int, int>(a, b);
    bg.RunWorkerAsync(argument: data);  
    

    然后在你的工作方法中

    void SlowMultiply(object sender, DoWorkEventArgs e)
            {
                var mydata = (Tuple<int, int>) e.Argument;
                int product = mydata.Item1 * mydata.Item2;
    
    
                for (int i = 1; i <= 5; i++)
                {
                    Thread.Sleep(500);
                }
    
                product = prod.ToString(); // update the global variable
            }       
        }
    

    或者,您可以计算Worker方法中的随机数。