C# WPF上位机开发(多线程中锁的使用)

news2025/2/2 16:00:32

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】

        多线程编程一般都会涉及到锁的时候,很多人可能觉得很意外,为什么会需要这么一个锁。本质上,这主要还是因为多线程的执行中,本身一部分逻辑并不是原子操作导致的。有一个池塘喂鱼的例子最为经典。假设池塘有两个人同时去喂鱼,每一个人喂鱼之前,会先看一下池塘边上的牌子。假设牌子是红色的,代表已经喂过了;假设牌子是绿色的,则代表鱼还没有喂过。鱼本身只能吃一顿,如果连续喂的话,那么鱼可能会撑死。

        现在就会出现这么一个情况,就是第一个人去喂鱼,但是他还没有来得及翻牌子的时候,第二个人来继续喂鱼。他一看鱼牌子是绿色的,还没有喂,那就就会选择继续投料。而他投料的同时,并不知道第一个人之前已经投喂过了。所以,这个时候,鱼就会被撑死了。

        所以,为了解决这个问题,os一般会提供一个锁的机制,对于锁里面的操作,一定是不能打断的。只有所有操作都完成之后,才会释放自己的锁机制。为了解释锁是怎么使用的,以及说明如果不用锁的话,究竟有什么样的坏处,可以通过c# wpf编写一个demo进行说明下。

1、设置界面

        界面还是只有一个按钮和一个textbox。按钮下去的时候,有两个thread同时递增1000万次,查看两个thread递增之后,总的数据次数是不是2000万。

<Window x:Class="WpfApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:sys="clr-namespace:System;assembly=mscorlib"
        xmlns:local="clr-namespace:WpfApp"
        mc:Ignorable="d"
        Title="LockSimulationDemo" Height="480" Width="550">
    <Grid>
        <StackPanel>
            <Button x:Name="button"  Content="Start processing" Click="StartButton_Click" Height="40" Margin="5,40"/>
            <TextBox x:Name="Result" TextWrapping="Wrap" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto" Height="200" Margin="5"/>
        </StackPanel>
    </Grid>
</Window>

        相关界面显示如下,

2、代码编写

        代码编写主要就是按钮的回调函数。回调函数中,主要使用了Thread类、ThreadStart类这两个。线程注册函数是WorkerThreadMethod。创建好两个thread之后,就可以将他们start开始执行。

        在线程注册函数中,会各循环1000万次。之所以会循环这么多次,是因为循环次数多了,才能看到锁的效果。没有锁的话,最终的累加次数不一定是2000万;反之,有了锁,肯定是2000万,这就是锁的用处所在。

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Threading;

namespace WpfApp
{
    public partial class MainWindow : Window
    {
        private int total = 0;
        private readonly object _lockObject = new object(); // lock for synchronization

        // construct function
        public MainWindow()
        {
            InitializeComponent();
        }

        // button invoke function
        private void StartButton_Click(object sender, RoutedEventArgs e)
        {
            Thread newThread1 = new Thread(new ThreadStart(WorkerThreadMethod));
            Thread newThread2 = new Thread(new ThreadStart(WorkerThreadMethod));

            Result.Text = "";
            total = 0;
            button.IsEnabled = false;

            newThread1.Start();
            newThread2.Start();
        }

        // thread entry function
        private void WorkerThreadMethod()
        {
            for (int i = 0; i < 10000000; i++)
            {
                lock (_lockObject) // critical section
                {
                    total += 1;
                }
            }

            Application.Current.Dispatcher.Invoke(() =>
            {
                Result.AppendText(total.ToString() + "\n");
                button.IsEnabled = true;
            });
        }
    }
}

3、实验和验证

        验证的话,编译没有啥问题,直接单击按钮即可。同时,这个按钮是可以连续单击,即一次结果出来之后可以反复测试的。中间测试的过程中,可以通过注释掉lock代码的方式,判断注释前后运行结果有没有差异。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1329007.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

深度学习中的损失函数

1 损失函数概述 大多数深度学习算法都会涉及某种形式的优化&#xff0c;所谓优化指的是改变以最小化或最大化某个函数 的任务&#xff0c;我们通常以最小化指代大多数最优化问题。 在机器学习中&#xff0c;损失函数是代价函数的一部分&#xff0c;而代价函数是目标函数的一种…

python脚本传参

sys.argvargparse 第一种&#xff1a;argparse 简单使用&#xff1a; import argparse # 创建一个参数解析实例 parser argparse.ArgumentParser(descriptionParameters) # 添加参数解析 parser.add_argument(--training_epoch, typeint, default3000) parser.add_argument(…

Layui 下拉select多选实现

1. html <div id"mo_deptment"></div> 2.引用 <script src"~/layuiadmin/layui/xm-select.js"></script>3.设置全局变量存储控件 var mo_deptmentSelect; 4.layui.use 中初始化 4.1 列表数据 var mo_deptmentdata [ …

Ubuntu 常用命令之 mkfs 命令用法介绍

&#x1f4d1;Linux/Ubuntu 常用命令归类整理 mkfs 是在 Linux 和其他 Unix-like 系统中用于创建文件系统的命令。在 Ubuntu 系统中&#xff0c;mkfs 命令也是用于创建文件系统的。mkfs 是一个包装器&#xff0c;它会根据用户指定的文件系统类型调用相应的程序。 mkfs 命令的…

第11章 GUI Page403~405 步骤三 设置滚动范围

运行效果&#xff1a; 源代码&#xff1a; /**************************************************************** Name: wxMyPainterApp.h* Purpose: Defines Application Class* Author: yanzhenxi (3065598272qq.com)* Created: 2023-12-21* Copyright: yanzhen…

【C语言】记录一次自己犯下的低级错误 o(╯□╰)o(局部数组与指针数组的传参、赋值)

在这里分享一下本人犯下的低级错误&#xff0c;希望大家别掉同样的坑 o(╥﹏╥)o 文章目录 事情原委错误分析及解救办法错误一&#xff1a; 使用局部数组arr并将其作为返回值解决方法&#xff1a;使用动态内存分配来创建数组&#xff0c;并在函数结束前手动释放内存。 错误二&…

Mac查询本机ip地址

Mac系统版本和网络配置不同&#xff0c;可能会有一些细微差别。 一、 使用系统偏好设置 1、点击屏幕左上角的Apple图标&#xff0c;选择“系统偏好设置”。 2、点击“网络”。 3、 在左侧选择当前连接的网络&#xff08;如Wi-Fi或以太网&#xff09;&#xff0c;在右侧界面&a…

在Linux系统中安装MySQL数据库

目录 一、MySQL简介 二、MySQL安装步骤 1、下载MySQL的YUM仓库文件 2、安装MySQL源 3、解决密钥异常问题 4、安装MySQL服务器 5、开启MySQL服务 6、查看MySQL服务器中root用户的初始密码 7、使用初始密码登录MySQL服务器 8、修改root用户登录MySQL服务器的密码 三、…

两个图片完美融合 泊松编辑

一、效果惊人 二、步骤 下载安装 https://github.com/Trinkle23897/Fast-Poisson-Image-Editing.git 执行 test 目录下的 python data.py下载数据 执行测试&#xff0c;可以看到效果了 $ fpie -s test1_src.jpg -m test1_mask.jpg -t test1_tgt.jpg -o result1.jpg -h1 -…

Python匹配文件模块的实战技巧

更多资料获取 &#x1f4da; 个人网站&#xff1a;ipengtao.com 在Python中&#xff0c;文件匹配是许多应用中常见的需求&#xff0c;例如文件管理、数据处理等。本文将深入探讨Python中用于文件匹配的模块&#xff0c;包括glob、fnmatch和os.path等&#xff0c;通过丰富的示例…

代码随想录算法训练营Day7 | 344.反转字符串、541.反转字符串||、替换数字、151.反转字符串中的单词、右旋字符串

LeetCode 344 反转字符串 本题思路&#xff1a;反转字符串比较简单&#xff0c;定义两个指针&#xff0c;一个 i 0, 一个 j s.length-1。然后定义一个临时变量 tmp&#xff0c;进行交换 s[i] 和 s[j]。 class Solution {public void reverseString(char[] s) {int i 0;int …

vitepress项目使用github的action自动部署到github-pages中,理论上可以通用所有

使用github的action自动部署到github-pages中 创建部署的deploy.yml文件&#xff0c;在项目的根目录下面 .github\workflows\deploy.yml 完整的代码&#xff1a;使用的是pnpm进行依赖安装。 name: 部署VitePresson:push:branches:- docs # 这段是在推送到 docs 分支时触发该…

学鸿蒙开发的过程,差点要了我的命!

我真的好想感慨一下&#xff0c;这个世界真的给计算机应届生留活路了吗&#xff1f; 看着周围的同学&#xff0c;打算搞前端、JAVA、C、C的&#xff0c;一个两个去跑去应聘。你以为是00后整治职场&#xff1f; 真相是主打一个卑微&#xff1a;现阶段以学习为主&#xff08;工资…

使用宝塔面板部署前端项目到服务器

目录 文章目录 前言 一、第一步&#xff1a;创建文件夹 二、第二步&#xff1a;部署前端项目 三、第三步&#xff1a;打开防火墙 文章目录 前言第一步&#xff1a;创建文件夹第二步&#xff1a;部署前端项目第三步&#xff1a;打开防火墙总结 前言 在此之前&#xff0c;我…

Vue3选项式API和组合式API详解

前言 相信学习Vue3的人中大多数都是之前使用Vue2开发的&#xff0c;当拿到一个Vue3项目时就接触到了组合式api&#xff0c;但对于组合式api不了解的人第一眼看上去会觉得一头雾水。&#xff1a;“什么玩意&#xff0c;乱七八糟的&#xff0c;选项式api多好&#xff0c;方法变量…

反序列化版本漏洞

laravel5.7反序列化漏洞 <?phpnamespace Illuminate\Foundation\Testing {class PendingCommand{public $test;protected $app;protected $command;protected $parameters;public function __construct($test, $app, $command, $parameters){$this->test $test; …

GLTF vs FBX:应该使用哪种格式?

在线工具推荐&#xff1a; 3D数字孪生场景编辑器 - GLTF/GLB材质纹理编辑器 - 3D模型在线转换 - Three.js AI自动纹理开发包 - YOLO 虚幻合成数据生成器 - 三维模型预览图生成器 - 3D模型语义搜索引擎 概括地说&#xff0c;如果要将数据传输到 Unity 或虚幻引擎等游戏引擎…

<蓝桥杯软件赛>零基础备赛20周--第11周--贪心

报名明年4月蓝桥杯软件赛的同学们&#xff0c;如果你是大一零基础&#xff0c;目前懵懂中&#xff0c;不知该怎么办&#xff0c;可以看看本博客系列&#xff1a;备赛20周合集 20周的完整安排请点击&#xff1a;20周计划 每周发1个博客&#xff0c;共20周。 在QQ群上答疑&#x…

集群与分布式的概念及区别

目前在工作中经常接触到集群的概念&#xff0c;通过这篇文章总结一下集群的几种方式以及和分布式对比学习 1.集群&#xff08;Cluster&#xff09; 集群是由多个计算机节点组成的网络&#xff0c;旨在共同提供服务&#xff0c;并确保高性能和高可用性。在高可用集群中&#xf…

EndNote插入参考文献

下载参考文献格式 复制刚刚下载的文件到endnote安装的位置下的Styles文件 重启endnote&#xff0c;在open style manager中勾选我们的格式 1.知网 下载&#xff0c;上传 可以attach PDF 分组 引用 2.Web of science 打开EndNote后&#xff0c;双击上面这个.ciw文件&#xff0c…