C# ASP.NET 线程入门教程

发布于 2024-08-15 23:55:41 字数 21356 浏览 9 评论 0

线程入门

创建线程

using system;
using system.Threading;

ThreadStart entry = new ThreadStart(CalcSum);
Thread workThread = new Thread(entry);
//or
Thread workThread = new Thread(new ThreadStart(CalcSum));  

//Method:
static void CalcSum()  
{  
     //do somethings.     
}

Thread 类几个重要方法

Thread 类用于创建线程,ThreadPool 类用于管理线程池。

Thread 类中几个重要的方法:
1. Start():启动线程;
2. Sleep(int):静态方法,暂停当前线程指定的毫秒数;
3. Abort():通常使用该方法来终止一个线程;
4. Suspend():该方法并不终止未完成的线程,它仅仅挂起线程,以后还可恢复;
5. Resume():恢复被 Suspend() 方法挂起的线程的执行。

Thread.ThreadState 属性

Thread.ThreadState 在各种情况下的取值如下:
1. Aborted:线程已停止
2. AbortRequested:线程的 Thread.Abort() 方法已被调用,但是线程还未停止
3. Background:线程在后台执行,与属性 Thread.IsBackground 有关(前台所有进程)
4. Running:线程正在正常运行
5. Stopped:线程已经被停止
6. StopRequested:线程正在被要求停止
7. Suspended:线程已经被挂起(此状态下,可以通过调用 Resume() 方法重新运行)
8. SuspendRequested:线程正在要求被挂起,但是未来得及响应
9. Unstarted:未调用 Thread.Start() 开始线程的运行
10. WaitSleepJoin:线程因为调用了 Wait(),Sleep() 或 Join() 等方法处于封锁状态 

设定线程优先级

优先级由高到低分别是 Highest,AboveNormal,Normal,BelowNormal,Lowest。默认为 ThreadPriority.Normal。

//示例:设定优先级为最低
myThread.Priority=ThreadPriority.Lowest;

线程的同步和通讯——生产者和消费者

假设这样一种情况,两个线程同时维护一个队列,如果一个线程对队列中添加元素,而另外一个线程从队列中取用元素,那么我们称添加元素的线程为生产者,称取用元素的线程为消费者。

lock 关键字

lock 关键字解决多个线程同时执行一个函数,导致数据的混乱,产生不可预料的结果的问题。
lock 关键字将一段代码定义为互斥段(critical section)。互斥段在一个时刻内只允许一个线程进入执行,而其他线程必须等待。
//定义如下:
lock(expression) statement_block

//expression 代表你希望跟踪的对象,通常是对象引用。一般地,保护一个类的实例,可以使用 this;保护一个静态变量(如互斥代码段在一个静态方法内部),一般使用类名就可以。
//statement_block 就是互斥段的代码,这段代码在一个时刻内只可能被一个线程执行。

Monitor 类(System.Threading)

Monitor 提供了使线程共享资源的方案。Monitor 类可以锁定一个对象,一个线程只有得到这把锁才可以对该对象进行操作。

......
Queue oQueue=new Queue();
......
Monitor.Enter(oQueue);
......//现在 oQueue 对象只能被当前线程操纵了
Monitor.Exit(oQueue);//释放锁

// 为了保证线程最终都能释放锁,你可以把 Monitor.Exit() 方法写在 try-catch-finally 结构中的 finally 代码块里。
// 当拥有对象锁的线程准备释放锁时,它使用 Monitor.Pulse() 方法通知等待队列中的第一个线程。

Monitor.Wait() 和 Monitor.Pulse()

1. Wait() 就是交出锁的使用权,使线程处于阻塞状态,直到再次获得锁的使用权。
2. 当前线程调用 Pulse() 向队列中的下一个线程发出锁的信号。接收到脉冲后,等待线程就被移动到就绪队列中。
在调用 Pulse 的线程释放锁后,就绪队列中的下一个线程(不一定是接收到脉冲的线程)将获得该锁。pulse() 并不会使当前线程释放锁。

实例:开辟一线程实现异步导出 Excel

环境介绍及实例简述

环境介绍:
开发语言》C#;
开发工具》Visual studio 2015;
Asp.Net MVC Version》5.2.3;
.Net Version》6.1.3;
NIPO version》2.2.1;

实例简述: 由于导出的 Excel 文件比较大,非常耗时,为了不影响对界面的其他操作,需要采用异步的方式进行导出。 具体实现方法就是后台开辟一个线程将 Excel 导出到指定目录,然后提供下载。

实现思路及准备工作

思路: 通过线程实现异步导出操作; 通过 NIPO 组件将数据存到 Excel 文件中。

准备工作:
1.下载 NPOI 组件, http://npoi.codeplex.com/ 
2.orcleHelper.dll

实例代码

UserController.cs

using Project.BLL;
using Project.Class;
using Project.Interface;
using Project.ViewModel;
using System;
using System.Collections.Generic;
using System.IO;
using System.Web.Mvc;
using System.Web.Script.Serialization;

namespace Project.UI
{
    /// <summary>
    /// 文件信息类
    /// </summary>
    public class FileInfoClass
    {
	public int count { set; get; }
	public IList<string> d_fileList { set; get; }
    }
    /// <summary>
    /// 用户控制器
    /// </summary>
    public class UserController : BaseController
    {
	//用户接口
	private IUserBLL iuser = new UserBLL();
	//返回信息
	private ReturnInfo returninfo = new ReturnInfo();

	/// <summary>
	/// 导出用户数据,返回文件列表
	/// </summary>
	public ActionResult UserInfoExportExcel()
	{
	    //搜索条件 Model 对象
	    SearchUserModel searchUserModel = new SearchUserModel();
	    //1.获取数据(具体如何获取数据,这里没有陈述)
	    List<UserViewModel> list = iuser.GetUserInfo(searchUserModel, ref returninfo) as List<UserViewModel>;

	    //2.调用方法,导出 Excel
	    //生成文件名称(改文件名称)
	    var fileName = string.Format("{0}用户信息表.xls", DateTime.Now.ToString("yyyyMMddHHssmm"));
	    //判断目录是否存在(该目录名称)
	    if (!Directory.Exists(Server.MapPath("~/Downloads/用户信息")))
	    {
		Directory.CreateDirectory(Server.MapPath("~/Downloads/用户信息"));
	    }
	    //将生成的文件保存到服务器临时文件夹中
	    string fullPath = Path.Combine(Server.MapPath("~/Downloads/用户信息"), fileName);
	    //表头
	    Dictionary<string, string> tableHeader = new Dictionary<string, string>
	    {
		{ "user_id","用户编号" },
		{ "username","用户名" },
		{ "sex","性别" },
		{ "age","年龄" },
		{ "tel","联系电话"},
		{ "email","邮箱"},
		{ "user_type", "用户类型" },
		{ "nickname", "用户昵称" }
	    };
	    //导出到 Excel。(Global.asax.cs)
	    MvcApplication._VehicleQueueT.Enqueue(new Classes.DataExportPara { excelPath=fullPath, sheetName = "用户信息", tableHeard= tableHeader, list =list});

	    //获取路径
	    string path = Server.MapPath("~/Downloads/用户信息");
	    //获取所有 xls 文件路径
	    IList<string> fileList = GetAllFileName(path);
	    FileInfoClass f_info = new FileInfoClass();
	    f_info.count = fileList.Count;
	    f_info.d_fileList = fileList;

	    //返回文件列表
	    return new ContentResult
	    {
		Content = new JavaScriptSerializer { MaxJsonLength = Int32.MaxValue }.Serialize(f_info),
		ContentType = "application/json"
	    };
	}
	/// <summary>
	/// 仅获取文件列表
	/// </summary>
	/// <returns></returns>
	public ActionResult GetFileLists()
	{
	    if (!Directory.Exists(Server.MapPath("~/Downloads/用户信息")))
	    {
		Directory.CreateDirectory(Server.MapPath("~/Downloads/用户信息"));
	    }
	    //路径
	    string path = Server.MapPath("~/Downloads/用户信息");
	    //
	    IList<string> fileList = GetAllFileName(path);

	    FileInfoClass f_info = new FileInfoClass();
	    f_info.count = fileList.Count;
	    f_info.d_fileList = fileList;
	    return new ContentResult
	    {
		Content = new JavaScriptSerializer { MaxJsonLength = Int32.MaxValue }.Serialize(f_info),
		ContentType = "application/json"
	    };
	}
	/// <summary>
	/// 删除文件
	/// </summary>
	/// <param name="fileName"></param>
	/// <returns></returns>
	public ActionResult DeleteFile(string fileName)
	{
	    string result = "";
	    //路径
	    string filePath = Server.MapPath("~/Downloads/用户信息/"+fileName);
	    if (!Directory.Exists(Server.MapPath("~/Downloads/已删除文件目录")))
	    {
		Directory.CreateDirectory(Server.MapPath("~/Downloads/已删除文件目录"));
	    }
	    string deletedFilePath = Server.MapPath("~/Downloads/已删除文件目录/"+fileName);
	    try
	    {
		//System.IO.File.Delete(filePath);
		//移动文件到"已删除文件目录"中
		FileInfo file = new FileInfo(filePath);
		file.MoveTo(deletedFilePath);
		result += "成功删除文件";
	    }
	    catch (Exception)
	    {
		result += "删除文件失败";
	    }
	    //返回操作结果
	    return Json(result, JsonRequestBehavior.AllowGet);
	}
	/// <summary>
	/// 获取目录下的所有 xls 文件
	/// </summary>
	/// <param name="path"></param>
	/// <returns></returns>
	private IList<string> GetAllFileName(string path)
	{
	    /*List<FileInfo> filelist = new List<FileInfo>();
	    //if (System.IO.File.Exists(path+"\\*.xls"))
	    var files = Directory.GetFiles(path, "*.xls");
	    foreach (var file in files)
	    {
		filelist.Add(new FileInfo(file));
	    }*/
	    IList<string> list = new List<string>();
	    DirectoryInfo folder = new DirectoryInfo(path);
	    foreach (FileInfo file in folder.GetFiles("*.xls"))
	    {
		list.Add(file.Name);
	    }
	    return list;
	}
    }
}

Global.asax.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Web;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;
using Project.Classes;

namespace GpsProject.UI
{
    public class MvcApplication : System.Web.HttpApplication
    {
	//数据导出队列
	public static Queue<DataExportPara> _VehicleQueueT = new Queue<DataExportPara>();

	protected void Application_Start()
	{
	    AreaRegistration.RegisterAllAreas();
	    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
	    RouteConfig.RegisterRoutes(RouteTable.Routes);
	    BundleConfig.RegisterBundles(BundleTable.Bundles);

	    OutputVehicleExcel();//注册信息导出方法
	}

	/// <summary>
	/// 导出信息
	/// </summary>
	public static void OutputVehicleExcel()
	{
	    DataExportPara exportPara = null;
	    ThreadPool.QueueUserWorkItem(o =>
	    {
		while (true)
		{
		    if (_VehicleQueueT != null && _VehicleQueueT.Count > 0)
		    {
			exportPara = _VehicleQueueT.Dequeue();
			if (exportPara != null)
			{
			    //调用方法
			    DataExport.ExportExcel(exportPara.excelPath, exportPara.sheetName, exportPara.tableHeard, exportPara.list);
			}
			else
			{
			    Thread.Sleep(6000);
			}
		    }
		    else
		    {
			Thread.Sleep(6000);
		    }
		}
	    });
	}
    }
}

DataExportPara.cs

using System.Collections;
using System.Collections.Generic;

namespace Project.Classes
{
    /// <summary>
    /// 数据导出 para
    /// </summary>
    public class DataExportPara
    {
	/// <summary>
	/// 导出路径
	/// </summary>
	public string excelPath { get; set; }
	/// <summary>
	/// 数据列表
	/// </summary>
	public IList list { get; set; }
	/// <summary>
	/// 工作表名称
	/// </summary>
	public string sheetName { get; set; }
	/// <summary>
	/// 表头
	/// </summary>
	public Dictionary<string, string> tableHeard {get;set;}
    }
}

DataExport.cs

using GpsProject.Class;
using System.Collections;
using System.Collections.Generic;
using System.IO;

namespace Project.Classes
{
    /// <summary>
    /// 数据导出
    /// </summary>
    public class DataExport
    {
	/// <summary>
	/// 导出 Excel 到目录
	/// </summary>
	/// <param name="path"></param>
	/// <param name="sheetName"></param>
	/// <param name="tableHeard"></param>
	/// <param name="list"></param>
	public static void ExportExcel(string path, string sheetName, Dictionary<string, string> tableHeard, IList list)
	{
	    using (var exportData = NPOIExcelHelper.ExportToExcelStream(list, sheetName, tableHeard))
	    {
		//创建一个文件
		FileStream file = new FileStream(path, FileMode.Create, FileAccess.Write);
		exportData.WriteTo(file);
		file.Close();
	    }
	}
    }
}

NPOIExcelHelper.cs

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using NPOI.SS.UserModel;
using System.Collections;

namespace Project.Class
{
    /// <summary>
    /// NPOI
    /// </summary>
    public class NPOIExcelHelper
    {
	/// <summary>
	/// 导出 Excel 到文件流
	/// </summary>
	/// <param name="dt"></param>
	/// <param name="sheetName"></param>
	/// <param name="tableHeard"></param>
	/// <returns>文件流</returns>
	public static MemoryStream ExportToExcelStream(IList lists, string sheetName, Dictionary<string, string> tableHeard)
	{
	    //创建一个工作簿
	    NPOI.HSSF.UserModel.HSSFWorkbook book = new NPOI.HSSF.UserModel.HSSFWorkbook();
	    NPOI.SS.UserModel.ISheet sheet = book.CreateSheet(sheetName); //创建 sheet

	    //Excel 表头
	    NPOI.SS.UserModel.IRow row = sheet.CreateRow(0); //创建行

	    ICellStyle style = book.CreateCellStyle(); //创建单元格
	    style.Alignment = HorizontalAlignment.Center; //对齐方式
	    style.VerticalAlignment = VerticalAlignment.Center;  //单元格居中对齐

	    #region 设置表头
	    List<string> headers = tableHeard.Keys.ToList();
	    for (int i = 0; i < headers.Count; i++)
	    {
		ICell cell = row.CreateCell(i);
		cell.CellStyle = style;
		cell.SetCellValue(tableHeard[headers[i]]);
	    }
	    /*for (int i = 0; i < dt.Columns.Count; i++)
	    {
		ICell cell = row.CreateCell(i);
		cell.CellStyle = style;
		cell.SetCellValue(dt.Columns[i].ColumnName);
	    }*/
	    #endregion

	    #region 填充数据
	    int rowIndex = 1;// 从第二行开始赋值(第一行已设置为单元头)
	    if (lists != null && lists.Count > 0)
	    {
		foreach (var list in lists)
		{
		    IRow rowTemp = sheet.CreateRow(rowIndex);
		    for (int i = 0; i < headers.Count; i++)
		    {
			string cellValue = ""; // 单元格的值
			object properotyValue = null; // 属性的值
			System.Reflection.PropertyInfo properotyInfo = null; // 属性的信息

			if (headers[i].IndexOf(".") > 0)
			{
			    // 3.1.1 解析子类属性(这里只解析 1 层子类,多层子类未处理)
			    string[] properotyArray = headers[i].Split(new string[] { "." }, StringSplitOptions.RemoveEmptyEntries);
			    string subClassName = properotyArray[0]; // '.'前面的为子类的名称
			    string subClassProperotyName = properotyArray[1]; // '.'后面的为子类的属性名称
			    System.Reflection.PropertyInfo subClassInfo = list.GetType().GetProperty(subClassName); // 获取子类的类型
			    if (subClassInfo != null)
			    {
				// 3.1.2 获取子类的实例
				var subClassEn = list.GetType().GetProperty(subClassName).GetValue(list, null);
				// 3.1.3 根据属性名称获取子类里的属性类型
				properotyInfo = subClassInfo.PropertyType.GetProperty(subClassProperotyName);
				if (properotyInfo != null)
				{
				    properotyValue = properotyInfo.GetValue(subClassEn, null); // 获取子类属性的值
				}
			    }
			}
			else
			{
			    // 3.2 若不是子类的属性,直接根据属性名称获取对象对应的属性
			    properotyInfo = list.GetType().GetProperty(headers[i]);
			    if (properotyInfo != null)
			    {
				properotyValue = properotyInfo.GetValue(list, null);
			    }
			}

			// 3.3 属性值经过转换赋值给单元格值
			if (properotyValue != null)
			{
			    cellValue = properotyValue.ToString();
			    // 3.3.1 对时间初始值赋值为空
			    if (cellValue.Trim() == "0001/1/1 0:00:00" || cellValue.Trim() == "0001/1/1 23:59:59")
			    {
				cellValue = "";
			    }
			}

			// 3.4 填充到 Excel 的单元格里
			ICell icellcontent = rowTemp.CreateCell(i);
			//icellcontent.CellStyle = Getcellstyle(workbook, cellStylecontent, fontcontent, stylexls.默认);
			icellcontent.SetCellValue(cellValue);
		    }
		    rowIndex++;
		    //达到 65535 行,跳出循环
		    if (rowIndex== 65535)
		    {
			break;
		    }
		}
	    }
	    else
	    {
		//导出空数据
		sheet.AddMergedRegion(new NPOI.SS.Util.CellRangeAddress(2, 2, 0, headers.Count - 1));
		IRow row2 = sheet.CreateRow(1);
		ICell icellkong = row2.CreateCell(0);
		//  icellkong.CellStyle = Getcellstyle(workbook, stylexls.默认);
		string str = "没有满足条件的数据可导出";
		icellkong.SetCellValue(str);
	    }

	    /* for (int i = 1; i <= dt.Rows.Count; i++)//遍历 DataTable 行
	 {
	     DataRow dataRow = dt.Rows[i - 1];
	     row = sheet.CreateRow(i);//在工作表中添加一行

	     for (int j = 0; j < dt.Columns.Count; j++)//遍历 DataTable 列
	     {
		 ICell cell = row.CreateCell(j);//在行中添加一列
		 cell.SetCellValue(dataRow[j].ToString());//设置列的内容   
	     }
	 }*/
	    #endregion

	    MemoryStream ms = new MemoryStream();
	    book.Write(ms);
	    return ms; //返回文件流
	}
    }
}

小结

在阅读别人的文章时,认真。

实例:利用线程监听模拟车辆进出智能化停车场

实例简述

实现效果

thread_20170616.png

主要代码

Main.cs

private void Main_Load(object sender, EventArgs e)
{
    MessagePrint.UpdateEventInfo += new MessagePrint.ShowEventInfoHandler(UpdateRuntimeInfo);
    //设置开始、结束时间为 00:00:00
    dateTimePicker_InStart.Text = ConfigInfoHelper.InStartRunTime;
    dateTimePicker_InEnd.Text = ConfigInfoHelper.InEndRunTime;
    dateTimePicker_OutStart.Text = ConfigInfoHelper.OutStartRunTime;
    dateTimePicker_OutEnd.Text = ConfigInfoHelper.OutEndRunTime;
    //获取默认时间
    BTModel.InStartRunTime = ConfigInfoHelper.InStartRunTime;
    BTModel.InEndRunTime = ConfigInfoHelper.InEndRunTime;
    BTModel.OutStartRunTime = ConfigInfoHelper.OutStartRunTime;
    BTModel.OutEndRunTime = ConfigInfoHelper.OutEndRunTime;
    vehicleio = new VehicleIO(BTModel);
    vehicleio.StartServer();
}
/// <summary>
/// 应用更改
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ApplyChanged_Click(object sender, EventArgs e)
{
    //先停止监听线程
    vehicleio.StopServer();
    BTModel.InStartRunTime = dateTimePicker_InStart.Text;
    BTModel.InEndRunTime = dateTimePicker_InEnd.Text;
    BTModel.OutStartRunTime = dateTimePicker_OutStart.Text;
    BTModel.OutEndRunTime = dateTimePicker_OutEnd.Text;
    vehicleio = new VehicleIO(BTModel);
    vehicleio.StartServer();
}

VehicleIO.cs

private string InStartRunTime="";//园区进场开启时间
private string InEndRunTime = "";//园区进场结束时间
private string OutStartRunTime = "";//园区出场开启时间
private string OutEndRunTime = "";//园区出场结束时间
public VehicleIO(RunTimeModel btModel)
{
    InStartRunTime = btModel.InStartRunTime;
    InEndRunTime = btModel.InEndRunTime;
    OutStartRunTime = btModel.OutStartRunTime;
    OutEndRunTime = btModel.OutEndRunTime;
}
private Thread thread = null;
//初始值
private int sendLocationInterval = 3;
//new 车辆进出园区数据模型
private VehicleIOModel iomodel = new VehicleIOModel();
/// <summary>
/// 开始服务
/// </summary>
public void StartServer()
{
    ThreadStart iothread = new ThreadStart(working);
    thread = new Thread(iothread);
    thread.Start();
}
/// <summary>
/// 停止服务
/// </summary>
public void StopServer()
{
    if (thread != null && thread.IsAlive)
    {
        thread.Abort();
    }
}
/// <summary>
/// 挂起服务
/// </summary>
public void SuspendServer()
{
    if (thread.ThreadState == ThreadState.Running)
    {
        thread.Suspend();
    }
}
/// <summary>
/// 恢复服务
/// </summary>
public void ResumeServer()
{
    if (thread.ThreadState == ThreadState.Suspended)
    {
        thread.Resume();
    }
}
/// <summary>
/// work.
/// </summary>
private void working()
{
    MessagePrint.SendEventInfo(1, true, "园区进出场系统开启!");
    while (true)
    {
        #region 进园区
        if (DateTime.Now.ToLongTimeString().Equals(InStartRunTime))
        {
            MessagePrint.SendEventInfo(1, true, "园区入场道口开启,车辆开始进入园区!");
            DataTable dtVehicleInInfo = null;
            try
            {
                //获取未入场的卡号
                dtVehicleInInfo = VehicleIODal.GetInstance().GetVehicleCardInInfo();
            }
            catch (Exception exc)
            {
                MessagePrint.SendEventInfo(1, true, "未能查询到数据,请检查数据库连接串" + exc);
            }
            if (dtVehicleInInfo.Rows.Count > 0)
            {
                MessagePrint.SendEventInfo(1, true, "已查询到所有可以进入园区的车辆数据,正在准备进入园区……");
                for (int i = 0; i < dtVehicleInInfo.Rows.Count; i++)
                {
                    string cardNo = dtVehicleInInfo.Rows[i]["card_no"].ToString();
                    MessagePrint.SendEventInfo(1, true, "卡号为“" + cardNo + "”的车辆,正在进入园区……");
                    //这里记录进入信息...略
                    //
                    //获取一个随机数(min 20,max 200,number 1)
                    int rand = Convert.ToInt32(getRandom(20, 150, 1));
                    MessagePrint.SendEventInfo(1, true, "下一辆车辆将在" + sendLocationInterval * rand / 60 + "分钟后抵达园区");
                    if (DateTime.Now.ToLongTimeString().Equals(InEndRunTime) || DateTime.Now.ToLongTimeString().CompareTo(InEndRunTime) > 0)
                    {
                        MessagePrint.SendEventInfo(1, true, "园区入场道口关闭,停止车辆入场!入场道口将会在 " + InStartRunTime + " 再次开启!");
                        break;
                    }
                    else
                    {
                        Thread.Sleep(sendLocationInterval * 1000 * rand);
                    }
                }
                MessagePrint.SendEventInfo(1, true, "注意:车辆进入园区操作完成!");
            }
            else
            {
                MessagePrint.SendEventInfo(1, true, "目前没有查询到要进入园区的车辆。");
            }
        }
        #endregion
        #region 出园区
        //与进园区代码一致,略
        #endregion
    }
}

其他

显示实时时间

#region 运行时显示实时时间
new Thread(() =>
{
    while (true)
    {
        try
        {
            labelTime.BeginInvoke(new MethodInvoker(() => labelTime.Text = DateTime.Now.ToString()));
        }
        catch (Exception)
        {

        }
        Thread.Sleep(1000);
    }
})
{ IsBackground = true }.Start();
#endregion

随机数获取

/// <summary>
/// 获取规定范围内的 n 个随机数
/// </summary>
/// <param name="min_value">随机数下限</param>
/// <param name="max_value">随机数上限</param>
/// <param name="number">随机数量</param>
/// <returns></returns>
private string getRandom(int min_value, int max_value, int number)
{
    Random random = new Random();
    ArrayList arr = new ArrayList();
    int temp = 0;
    for (int i = 0; i < number; i++)
    {
        temp = random.Next(min_value, max_value); //随机取数
        arr.Add(temp);
    }
    string str = "";
    for (int j = 0; j < arr.Count; j++)
    {
        str += arr[j].ToString() + ",";
    }
    return str.Substring(0, str.LastIndexOf(","));
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

幽梦紫曦~

暂无简介

0 文章
0 评论
22 人气
更多

推荐作者

我们的影子

文章 0 评论 0

素年丶

文章 0 评论 0

南笙

文章 0 评论 0

18215568913

文章 0 评论 0

qq_xk7Ean

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文