从零开始的C#窗体应用与多线程保姆级教程:小白也能快速上手

3 篇文章 0 订阅
1 篇文章 0 订阅

前言

        作为一名编程爱好者,我深知C#入门编程的挑战。每次更新原创内容,都是希望能帮助更多初学者突破技术壁垒。今天这篇文章,我将用保姆级的讲解方式,带你从零开始,学会如何在C#中创建一个简单的窗体应用,并使用多线程来处理任务。即使你从未接触过编程,也能轻松跟上!

        坚持原创更新并不容易,但每当看到有人因我的教程而受益,我便觉得一切都是值得的。

你的点赞和关注是我前行的最大动力!

一、准备工作

1. 安装Visual Studio

首先,你需要安装Visual Studio,这是一个功能强大的集成开发环境(IDE),支持多种编程语言,包括C#。你可以前往Visual Studio官网下载并安装Community版本。

       (下载安装Visual Studio教程网络上很多,博主这里就不在赘述,相信大家学习过程中都安装了吧!)

这个教程特别适合初学者,内容详细且易于理解。

先展示一下C#窗体应用与多线程结果展示图:

2. 创建一个新的Windows Forms项目

安装好Visual Studio后,按照以下步骤创建一个Windows Forms应用程序:

  1. 打开Visual Studio,点击“创建新项目”。

2.在搜索框中输入“Windows Forms”,选择“Windows Forms App (.NET Framework)”并点击“下一步”。

3.输入项目名称(例如MyFirstApp,命名自行设计,符合C语言文件命名规范即可),选择存放路径,然后点击“创建”。

4.Visual Studio会自动生成一个窗体应用的基础框架,并打开一个设计器(即工具箱和属性)窗口,你可以在这里拖放控件来设计你的界面。

二、从零开始编写代码

现在我们已经创建好了一个基础的Windows Forms项目,接下来我们开始编写代码,并一步步实现多线程功能。

1. 添加控件

首先,我们需要在窗体上添加一些控件,用于演示多线程的操作:

  1. 在设计器窗口左侧的“工具箱”中找到“Button”和“Label”控件。
  2. 将三个Button控件和两个Label控件拖放到窗体上。
  3. 选中第一个Label,在右侧的“属性”窗口中,将其Name属性设置为label1,并将Text属性设置为空。
  4. 选中第一个Button,将其Name属性设置为button1,并将Text属性改为“开始抢票”。
  5. 对第二个ButtonLabel控件重复上述操作,将Name属性分别设置为button2label3,并将Text属性设置为空。
  6. 对第三个Button控件,将Name属性设置为button4,将Text属性设置为“线程开启”。
  7. 另外几个控件照对应添加即可。

2. 编写多线程代码

接下来,我们开始编写与多线程相关的代码。在Visual Studio中,双击每个Button控件,这将自动生成点击事件处理程序。将以下完整代码粘贴到生成的代码区域:

using System;
using System.Threading;
using System.Windows.Forms;

namespace _20240829
{
    public partial class FormThread : Form
    {
        public FormThread()
        {
            InitializeComponent();
            label1.Text = "当前票数:>" + ticket.ToString();
            Thread.CurrentThread.Name = "我是主线程";
        }

        int ticket = 2;  // 初始票数为2
        object suo = new object();  // 创建锁对象

        // 抢票逻辑
        void GrabTicket()
        {
            lock (suo)
            {
                if (ticket > 0)
                {
                    Thread.Sleep(1000);  // 模拟抢票延迟
                    ticket--;
                    Console.WriteLine(Thread.CurrentThread.Name + " 抢票成功");
                }
                else
                {
                    Console.WriteLine(Thread.CurrentThread.Name + " 抢票失败");
                }
            }
        }

        // 开始抢票按钮点击事件
        private void button1_Click(object sender, EventArgs e)
        {
            for (int i = 0; i < 10; i++)
            {
                int index = i;
                Thread thread = new Thread(() =>
                {
                    GrabTicket();
                });
                thread.Name = "ID" + index.ToString();
                thread.Start();
            }
        }

        // 更新票数按钮点击事件
        private void button2_Click(object sender, EventArgs e)
        {
            label1.Text = "当前票数:>" + ticket.ToString();
        }

        Thread thread;
        bool flag = true;

        // 开始计数按钮点击事件
        private void button4_Click(object sender, EventArgs e)
        {
            int a = 0;
            thread = new Thread(() =>
            {
                while (flag)
                {
                    a++;
                    if (this.InvokeRequired)
                    {
                        this.Invoke(new Action(() =>
                        {
                            label3.Text = a.ToString();
                        }));
                        Thread.Sleep(500);
                    }
                    else
                    {
                        label3.Text = a.ToString();
                        Thread.Sleep(500);
                    }
                }
            });
            thread.Name = "我是子线程";
            thread.Start();
        }

        // 停止计数按钮点击事件
        private void button3_Click(object sender, EventArgs e)
        {
            flag = false;
            thread.Abort();
        }

        // 运行指定ID的线程
        void Run(int ID)
        {
            Console.WriteLine("ID" + ID);
        }

        Thread threadTest;

        // 启动多个线程按钮点击事件
        private void button5_Click(object sender, EventArgs e)
        {
            for (int i = 1; i <= 20; i++)
            {
                int index = i;
                threadTest = new Thread(() =>
                {
                    Run(index);
                });
                threadTest.Start();
            }
        }
    }
}
3. 代码解析
  • 票数初始化:我们定义了一个ticket变量,用于模拟剩余票数。
  • 锁机制lock语句用于确保同一时刻只有一个线程可以访问共享资源ticket,防止多线程同时修改数据造成错误。
  • 线程启动button1_Click事件中,使用for循环创建并启动了10个线程,每个线程都会尝试抢票。
  • 计数线程button4_Click事件中,通过创建新线程不断增加变量a的值,并更新label3的显示内容。
  • 线程安全:在更新UI控件时,使用InvokeRequired判断是否需要主线程帮助更新,以确保线程安全。
3. 运行项目并观察结果

点击Visual Studio顶部的“启动”按钮(或按下F5键),运行项目。在窗体上点击“开始抢票”按钮,你会看到控制台输出抢票的结果。

点击“更新票数”按钮,查看剩余票数。

点击“开始计数”按钮,观察label3显示的计数值逐渐增加。

三、应对挑战与心得

        在编写多线程应用时,你可能会遇到线程安全的问题,比如多个线程同时访问和修改共享资源。在本文中,我通过lock机制确保了线程的安全性。对于初学者而言,理解和掌握这些概念可能需要一些时间,但只要多加练习,一定会有所收获。

四、总结

        通过这篇保姆级教程,我们从零开始创建了一个简单的Windows Forms应用,并学习了如何在C#中实现多线程操作。希望这篇文章能够帮助你打下坚实的编程基础,并激发你对C#开发的兴趣。

结束语

        需要源代码或文件的,可以主页找博主,分享给一路学习,一路奋进的你们。

        每一次原创更新,都是我对编程的热爱与坚持的体现。如果你觉得这篇文章对你有帮助,请点赞、收藏并关注,这将激励我持续更新更多优质内容!


  • 14
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值