c# - 如何避免线程应用程序中的全局变量
问题描述
我制作了一个简单的应用程序,它使用后台工作人员调用执行缓慢的任务。我希望能够将一些参数传递给慢速函数并在任务完成时获得结果。我可以通过使用全局变量 a、b 和产品来做到这一点。有没有更好的方法将参数传递给慢速函数并取回结果?
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
}
}
}
解决方案
您可以像这样通过后台工作人员发送参数:
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
}
}
或者,您可以只计算您的工作方法中的随机数。
推荐阅读
- orientdb - Gremlin:通过“name”属性查找顶点的重复项并作为“id”列表执行
- sql - 动态插入语句需要返回被插入的ID
- c# - 使用 Parallel.ForEach 与 TPL.Dataflow 或其他解决方案将 OCR 应用于大量图像
- javascript - 为什么 setTimeout 在指定时间后不触发
- java - 如何使用现代网站的 Jsoup 访问 html?
- mysql - BEGIN;COMMIT; 的替代方法 因为交易影响了我使用 LAST_INSERT_ID() 的能力?
- python - Python GPy 模块:如何在简单的 x 轴上绘制模型预测?
- swift - 如何从 Swift 应用程序设置辅助功能首选项?
- elasticsearch - Stormcrawler - es.status.filterQuery 是如何工作的?
- python - 我需要从 CSV 文件中读取,并写入一个包含 0 个重复项的新 CSV 文件