Windows 11 设备没有网络连接,可以选择「我没有 Internet 连接」;
如果你使用的安装映像版本比较老,在此步骤时,需要先按下键盘Shift + F10快捷键,再在弹出的命令行窗口中执行OOBE\BYPASSNRO命令后才可以选择「我没有 Internet 连接」
Win11 装系统 Memory
C# 多线程
进程/线程/多线程
- 进程:计算机概念,虚拟的记录,描述一个应用程序在计算机上运行时,所消耗的各种机资源集合—Cpu+内容+磁盘IO+网络资源。
- 线程:一个程序的进程中,所执行的具体的某一个动作的最小执行流。
- 句柄:是一个long类型的数字,对应着计算机程序中的某一个小部件。
- 进程中包括多个线程;线程依附于进程存在。
- 线程:—同步异步
- CPU是分片执行:比如把每一个核每一秒钟可以执行的动作切分成10000份,操作系统执行多个动作时,开始动作A,使用了分片后的某一份,结束的时候可能是另外的谋一份
C#中的多线程:Thread/ThreadPool/Task
Thread.Sleep和Task.Delay区别
{
Stopwatch stopwatch = Stopwatch.StartNew();
stopwatch.Start();
Thread.Sleep(3000);//主线程延迟3000毫秒,会卡界面
stopwatch.Stop();
Debug.WriteLine($"Sleep:3000:{stopwatch.ElapsedMilliseconds}");
}
{
//Task.Delay一般和ContinueWith搭配,意指延迟一段时间(例3000毫秒)后去做一些事
Stopwatch stopwatch = Stopwatch.StartNew();
stopwatch.Start();
Task.Delay(3000).ContinueWith<int>(t =>
{
stopwatch.Stop();
Debug.WriteLine($"Dely:3000:{stopwatch.ElapsedMilliseconds}");
var a= DoSomethingInt();
return a;
});//延迟3000毫秒执行
}
/*ContinueWith有可能会使用主线程其中会*/
等待线程结束(taskFactory.ContinueWhenAny和WaitAny)
List<Task> tasks = new List<Task>();
TaskFactory taskFactory = new TaskFactory();
//不带参数
tasks.Add(taskFactory.StartNew(() => { DoSomethingInt("1"); }));
tasks.Add(taskFactory.StartNew(() => { DoSomethingInt("2"); }));
tasks.Add(taskFactory.StartNew(() => { DoSomethingInt("3"); }));
tasks.Add(taskFactory.StartNew(() => { DoSomethingInt("4"); }));
tasks.Add(taskFactory.StartNew(() => { DoSomethingInt("5"); }));
//Task.WaitAny会卡顿界面
//Task.WaitAny(tasks.ToArray());
//taskFactory.ContinueWhenAny不会卡顿界面
taskFactory.ContinueWhenAny(tasks.ToArray(), t => { Debug.WriteLine("Any Task is Completed"); });
//带参数的情况
tasks.Add(taskFactory.StartNew(t => { DoSomethingInt(Convert.ToString(t)); }, "1"));
tasks.Add(taskFactory.StartNew(t => { DoSomethingInt(Convert.ToString(t)); }, "2"));
tasks.Add(taskFactory.StartNew(t => { DoSomethingInt(Convert.ToString(t)); }, "3"));
tasks.Add(taskFactory.StartNew(t => { DoSomethingInt(Convert.ToString(t)); }, "4"));
tasks.Add(taskFactory.StartNew(t => { DoSomethingInt(Convert.ToString(t)); }, "5"));
//Task.WaitAny(tasks.ToArray());
taskFactory.ContinueWhenAny(tasks.ToArray(), t => { Debug.WriteLine($"Task [{t.AsyncState}] is Completed"); });
WaitAll和TaskFactory.ContinueWhenAll也是一个意思
C#线程传递参数的方式
方式一:使用ParameterizedThreadStart委托
using System;
using System.Threading;
namespace ConsoleLearn
{
class Program
{
static void Main(string[] args)
{
Thread thread = new Thread(new ParameterizedThreadStart(SayHello));
thread.Start("zhangsan");
//简写
//Thread thread = new Thread(SayHello);
//thread.Start("zhangsan");
Console.ReadKey();
}
public static void SayHello(object name)
{
if (!string.IsNullOrEmpty(name as string))
{
Console.WriteLine($"Hello! {name}");
}
}
}
}
可以看出ParameterizedThreadStart是底层自定义的一个只有一个object参数,无返回值的委托,所以传递方法的时候需要一个只有一个object参数,且返回类型为void的方法(委托实质就是同一种类型方法的抽象)
方法二:定义自定义类:
using System;
using System.Threading;
namespace ConsoleLearn
{
public class MyThread
{
private string name;
public MyThread(string name)
{
this.name = name;
}
public void SayHello()
{
Console.WriteLine($"Hello{name}");
}
}
class Program
{
static void Main(string[] args)
{
//Thread thread = new Thread(new ParameterizedThreadStart(SayHello));
//thread.Start("zhangsan");
//简写
//Thread thread = new Thread(SayHello);
//thread.Start("zhangsan");
MyThread myThread = new MyThread("zhangsan");
Thread thread = new Thread(myThread.SayHello);
thread.Start();
Console.ReadKey();
}
public static void SayHello(object name)
{
if (!string.IsNullOrEmpty(name as string))
{
Console.WriteLine($"Hello! {name}");
}
}
}
}
可以看出,实质就是将参数封装在一个类中,实例化的时候将参数传递进去
方式三:Lambda表达式:
using System;
using System.Threading;
namespace ConsoleLearn
{
public class MyThread
{
private string name;
public MyThread(string name)
{
this.name = name;
}
public void SayHello()
{
Console.WriteLine($"Hello{name}");
}
}
class Program
{
static void Main(string[] args)
{
Thread thread = new Thread(()=>SayHello("zhangsan"));
thread.Start();
Console.ReadKey();
}
public static void SayHello(string name)
{
if (!string.IsNullOrEmpty(name as string))
{
Console.WriteLine($"Hello! {name}");
}
}
}
}
以上就是线程间传递参数的三种方式
递归查询
数据表
数据结构
sql语句
查询结果
解释
设定起点(起点可以是多个,但是可能重复)
从empno=7839的记录开始
查询empno和mgr的数据相同的记录
直接查询到底,再逐步往上往后
(其中Prior代表的是选定的当前行的的某个字段,也就是寻找与当前行中prior标注的字段的值相同的下一条记录)
部分函数
connect_by_root 找所有根节点
connect_by_isleaf 找所有叶子节点
gitee的使用文档
1、gitee是什么?
基于git的代码托管协助平台
2、git网站上的注册登录
2.1 打开gitee官网Gitee – 基于 Git 的代码托管和研发协作平台打开注册登录即可。邮箱注册最好,非邮箱在个人-设置里添加自己的邮箱。
新手请公开自己的邮箱,如图:
3、准备工作
3.1、工具一:git-bit的安装,gateio安装教程看这个。
3.2、工具二:TortoiseGit.msi小乌龟(可选软件)
这个软件是为了图形化的方式。安装有先后顺序。
3.3、配置RSA公钥
3.3.1 打开git bash,在哪里鼠标右键都行,因为目前还在配置。
3.3.2 输入代码来实现git账户和本地的关联。
ssh-keygen -t rsa -C "你的邮箱"
一直回车,一共三次,虽然出现了冒号,但是不用填。
3.3.3 结束后输入来查看自己的密钥:
cat ~/.ssh/id_rsa.pub
- 3.3.4 将下面的密钥全部复制到网站上去:在官网—个人—设置—ssh公钥—下面的公钥文本域(大的输入框)复制进去—上面的标题是随意改的,给自己看的—确定。
- 3.3.5 测试是否连接到远程自己的账号。
- 3.3.6 创建远程仓库 打开官网,新建仓库。创建成功跳转过后,点击克隆下载,然后复制ssh的地址来进行上传下载(后面会用到地址)
4、上传文件到gitee
4.1 新建文件夹/进入解决方案文件夹
4.2 进入刚刚新建的文件夹,即进入“gitspace”,点击鼠标右键,选择”Git Bash Here”,如下图:
4.3 进行基础配置,也叫全局设置,作为 git 的基础配置,作用是告诉 git 你是谁,你输入的信息将出现在你创建的提交中,使用下面两条命令:
git config --global user.name "你的名字或昵称"
git config --global user.email "你的邮箱"
5、下载自己的仓库和别人的
5.1 新建个文件夹方便看,进入到这个文件夹,鼠标右键-打开git bash命令窗口–复制网站上的ssh链接-在刚才的Git窗口中输入命令 git clone 然后右键即可。
git clone url
6、基本命令汇总
6.1 Git 的工作就是创建和保存你项目的快照及与之后的快照进行对比。他有四个位置:
- workspace:工作区
- staging area:暂存区/缓存区
- local repository:版本库或本地仓库
- remote repository:远程仓库
git init 初始化仓库
git clone 拷贝一份远程仓库,也就是下载一个项目。
git add 添加文件到暂存区
git status 查看仓库当前的状态,显示有变更的文件。
git diff 比较文件的不同,即暂存区和工作区的差异。
git commit 提交暂存区到本地仓库。
git reset 回退版本。
git rm 删除工作区文件。
git mv 移动或重命名工作区文件。
git log 查看历史提交记录
git blame <file> 以列表形式查看指定文件的历史修改记录
git remote 远程仓库操作
git fetch 从远程获取代码库
git pull 下载远程代码并合并
git push 上传远程代码并合并
6.2 其他常见git命令
查看所有分支 :git branch -a
切换到某一分支:git checkout 分支名称
合并分支:git merge 原分支 目标分支
4.更新代码到本地 git status(查看本地分支文件信息,确保更新时不产生冲突)
git checkout — [file name] (若文件有修改,可以还原到最初状态; 若文件需要更新到服务器上,应该先merge到服务器,再更新到本地)
git branch(查看当前分支情况)
git checkout remote branch
git pull
若命令执行成功,则更新代码成功!
可以直接使用: git pull 命令一步更新代码
7、VS开发工具集成使用Git工具
安装Git Extensions 工具即可
C# Socket(TCP)客户端
public class Client
{
private string _ip = string.Empty;
private int _port = 0;
private Socket _socket = null;
private byte[] _buffer = new byte[1024 * 1024 * 2];
//创建事件将数据传输到UI
Informations _informations;
//监听Task
private Task _task;
//Task Token
private static CancellationTokenSource cancelTokenSource = new CancellationTokenSource();
public Client(string ip,int port,Informations informations)
{
_ip = ip;
_port = port;
_informations = informations;
}
public Client( int port, Informations informations)
{
_port = port;
_ip = IPAddress.Any.ToString();
_informations = informations;
}
//开始监听
public void StartClient()
{
try
{
//创建套子
_socket = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
//创建连接目标的IP
IPAddress address = IPAddress.Parse( _ip );
//创建连接目标的端点
IPEndPoint iPEndPoint = new IPEndPoint(address, _port);
//连接端点
_socket.Connect(iPEndPoint);
_informations.Invoke("连接服务器成功");
//开始监听目标的信息
Task.Factory.StartNew(() => ReceiveMsg(), cancelTokenSource.Token);
}
catch (Exception ex)
{
_socket.Shutdown(SocketShutdown.Both);
_socket.Close();
_informations.Invoke(ex.Message);
}
}
//接收信息
private void ReceiveMsg()
{
while (true)
{
Byte[] buffer = new Byte[1024 * 1024 * 2];
int length = _socket.Receive(buffer);
if (buffer.Length > 0)
{
_informations.Invoke($"接收服务器 {_ip},消息:{Encoding.UTF8.GetString(buffer,0, length)}");
}
}
}
//关闭连接
public void CloseConnection()
{
cancelTokenSource.Cancel();
_socket.Close();
}
//发送信息
public void SendMsg(string a)
{
string sendMessage = $"{DateTime.Now.ToString()}: a";
_socket.Send(Encoding.UTF8.GetBytes(a));
}
}
C# Socket(TCP)服务端
public class ServerSocket
{
private string _ip = string.Empty;
//创建的事件用于传递数据到UI上
Infomation _infomation = null;
//端口号
private int _port = 0;
//服务端通道
private Socket _socket = null;
private byte[] _buffer = null;
Task _task;
//通道字典
Dictionary<string, Socket> _socketDictory = new Dictionary<string,Socket>();
//Task Token字典
Dictionary<string, CancellationTokenSource> tokenSourcekeyValuePairs = new Dictionary<string, CancellationTokenSource>();
//
public ServerSocket(string ip,int port,Infomation infomation)
{
_port= port;
_ip = ip;
_infomation = infomation;
}
public ServerSocket(int port, Infomation infomation)
{
_port= port;
_infomation = infomation;
_ip = IPAddress.Any.ToString();
}
//创建套子设置连接数,开始监听
public void StartListen()
{
try
{
//1.0 实例化套接字(IP4寻找协议,流式协议,TCP协议)
_socket = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
//2.0 创建IP对象
IPAddress iPAddress = IPAddress.Parse(_ip);
//3.0 创建网络端口,包括ip和端口
IPEndPoint iPEndPoint = new IPEndPoint(iPAddress, _port);
//4.0 绑定套接字
_socket.Bind(iPEndPoint);
//5.0 设置最大连接数
_socket.Listen(int.MaxValue);
_infomation.Invoke($"监听{_socket.LocalEndPoint.ToString()}消息成功");
//6.0 开始监听
Task.Run(() => ListenClientConnect());
}
catch (Exception ex)
{
throw;
}
}
//监听客户端的连接请求
private void ListenClientConnect()
{
try
{
while (true)
{
Socket clientSocket = _socket.Accept();
if (clientSocket != null)
{
_socketDictory.Add(clientSocket.RemoteEndPoint.ToString(), clientSocket);
CancellationTokenSource tokenSource = new CancellationTokenSource();
tokenSourcekeyValuePairs.Add(clientSocket.RemoteEndPoint.ToString(), tokenSource);
clientSocket.Send(Encoding.UTF8.GetBytes("服务端发送消息:"));
Task.Factory.StartNew(() => ReceiveMessage(clientSocket), tokenSource.Token);
}
}
}
catch (Exception)
{
throw;
}
}
//发送信息
public void SendMessage(string msg)
{
if (_socketDictory.Count != 0)
{
Socket socket = _socketDictory.First().Value;
socket.Send(Encoding.UTF8.GetBytes(msg));
_infomation.Invoke($"{socket.LocalEndPoint} To {socket.RemoteEndPoint}: {msg}");
}
else
{
_infomation.Invoke($"没有连接到任何用户");
}
}
//关闭连接
public void close()
{
foreach (var item in tokenSourcekeyValuePairs)
{
item.Value.Cancel();
}
tokenSourcekeyValuePairs.Clear();
foreach (var item in _socketDictory)
{
item.Value.Close();
}
_socketDictory.Clear();
}
//接收信息
private void ReceiveMessage(object socket)
{
Socket clientSocket = (Socket)socket;
byte[] buffer = new byte[1024];
while (true)
{
try
{
int length = clientSocket.Receive(buffer);
if (length > 0)
{
_infomation.Invoke($"接收客户端{clientSocket.RemoteEndPoint.ToString()},消息{Encoding.UTF8.GetString(buffer, 0, length)}");
}
}
catch (Exception ex)
{
_infomation.Invoke(ex.Message);
clientSocket.Shutdown(SocketShutdown.Both);
clientSocket.Close();
break;
}
}
}
}
Nlog引入.net
Nugget包引入
Nlog.Web.AspNetCore
编写配置文件(nlog.config)
<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.nlog-project.org/schemas/NLog.xsd NLog.xsd"
autoReload="true"
throwExceptions="false"
internalLogLevel="Off" internalLogFile="c:\temp\nlog-internal.log">
<!-- optional, add some variables
https://github.com/nlog/NLog/wiki/Configuration-file#variables
-->
<variable name="myvar" value="myvalue"/>
<!--
See https://github.com/nlog/nlog/wiki/Configuration-file
for information on customizing logging rules and outputs.
-->
<targets>
<target name="AllDatabase" xsi:type="Database"
dbProvider="System.Data.SqlClient.SqlConnection,System.Data.SqlClient"
connectionString="Data Source=PC-202206030027;Initial Catalog=LogManager;User ID=sa;Password=sa123;"
commandText="insert into dbo.NLog (Application, Logged, Level, Message,Logger, CallSite, Exception) values (@Application, @Logged, @Level, @Message,@Logger, @Callsite, @Exception);">
<parameter name="@application" layout="AspNetCoreNlog" />
<parameter name="@logged" layout="${date}" />
<parameter name="@level" layout="${level}" />
<parameter name="@message" layout="${message}" />
<parameter name="@logger" layout="${logger}" />
<parameter name="@callSite" layout="${callsite:filename=true}" />
<parameter name="@exception" layout="${exception:tostring}" />
</target>
<target xsi:type="File" name="allfile" fileName="NLog\nlog-all-${shortdate}.log"
layout="${longdate}|${logger}|${uppercase:${level}}|${message} ${exception}" />
<!--同样是将文件写入日志中,写入的内容有所差别,差别在layout属性中体现。写入日志的数量有差别,差别在路由逻辑中体现-->
<target xsi:type="File" name="ownFile-web" fileName="NLog\nlog-my-${shortdate}.log"
layout="${longdate}|${logger}|${uppercase:${level}}|${message} ${exception}" />
<target xsi:type="Null" name="blackhole" />
<!--
Write events to a file with the date in the filename.
<target xsi:type="File" name="f" fileName="${basedir}/logs/${shortdate}.log"
layout="${longdate} ${uppercase:${level}} ${message}" />
-->
</targets>
<rules>
<!-- add your logging rules here -->
<logger name="*" minlevel="debug" writeTo="AllDatabase" />
<!--路由顺序会对日志打印产生影响。路由匹配逻辑为顺序匹配。-->
<!--All logs, including from Microsoft-->
<logger name="*" minlevel="Trace" writeTo="allfile" />
<!--Skip Microsoft logs and so log only own logs-->
<!--以Microsoft打头的日志将进入此路由,由于此路由没有writeTo属性,所有会被忽略-->
<!--且此路由设置了final,所以当此路由被匹配到时。不会再匹配此路由下面的路由。未匹配到此路由时才会继续匹配下一个路由-->
<logger name="Microsoft.*" minlevel="Trace" final="true" />
<!--上方已经过滤了所有Microsoft.*的日志,所以此处的日志只会打印除Microsoft.*外的日志-->
<logger name="*" minlevel="Trace" writeTo="ownFile-web" />
<!--
Write all events with minimal level of Debug (So Debug, Info, Warn, Error and Fatal, but not Trace) to "f"
<logger name="*" minlevel="Debug" writeTo="f" />
-->
</rules>
</nlog>
Program位置添加Nlog配置
LogManager.Setup().LoadConfigurationFromFile("CfgFile/nLog.config"/*此处为配置文件路径*/).GetCurrentClassLogger();
builder.Host.UseNLog();
注入
private readonly ILogger<BlogNews> _logger;
private readonly ILoggerFactory _ILoggerFactory;
public BlogNews(IBlogNewsService blogNewsService, ILogger<BlogNews> logger, ILoggerFactory loggerFactory)
{
_logger = logger;
_logger.LogInformation($"_ILogger:{GetType().FullName} 被构造~~");
_ILoggerFactory = loggerFactory;
ILogger<BlogNews> _ILogger2 = _ILoggerFactory.CreateLogger<BlogNews>();
_ILogger2.LogError($"_ILogger2: {GetType().FullName} 被构造~~");
}
C# 同步异步
线程,进程
进程:描述的是一个应用程序在计算机上运行时所有消耗资源的集合—-CPU,内容,磁盘IO,网络资源
线程:一个程序在进程中所执行的具体某一个动作的最小执行流—-某个按钮,网络发送信息
句柄:是一个long类型的数字,对应计算机的某一个小部件
进程一定是包含了多个线程:线程是依附于进程存在的。
c# AutoMapper
概要
可以自动的在类与类之间进行映射
引入包
AutoMapper.Extensions.Microsoft.DependencyInjection
类
public class BlogNews:BaseId
{
//nvarchar带中文比较好
[SugarColumn(ColumnDataType ="nvarchar(30)")]
public string Title { get; set; }
[SugarColumn(ColumnDataType ="text")]
public string Content { get; set; }
public DateTime Time { get; set; }
public int BrowseCount { get; set; }
public int LikeCount { get; set; }
public int TypeId { get; set; }
public int WriterId { get; set; }
/// <summary>
/// 类型,不映射到数据库
/// </summary>
[SugarColumn(IsIgnore =true)]
public TypeInfo TypeInfo { get; set; }
[SugarColumn(IsIgnore = true)]
public WriterInfo WriterInfo { get; set; }
}
public class BlogNewsDTO
{
public int Id { get; set; }
public string Title { get; set; }
public string Content { get; set; }
public DateTime Time { get; set; }
public int BrowseCount { get; set; }
public int LikeCount { get; set; }
public int TypeId { get; set; }
public int WriterId { get; set; }
public string TypeName { get; set; }
public string WriterName { get; set; }
}
映射类的设置
public class CustomAutoMapperProfile : Profile
{
public CustomAutoMapperProfile()
{
//名字相同的属性会进行自动映射
base.CreateMap<WriterInfo, WriterDTO>();
base.CreateMap<BlogNews, BlogNewsDTO>()
//将BlogNews.TypeInfo.Name映射到BlogNewsDTO.TypeName
.ForMember(dest => dest.TypeName, sourse => sourse.MapFrom(src => src.TypeInfo.Name))
//将BlogNews.WriterInfo.Name映射到BlogNewsDTO.WriterName
.ForMember(dest => dest.WriterName, sourse => sourse.MapFrom(src => src.WriterInfo.Name));
}
}
配置中间件
builder.Services.AddAutoMapper(typeof(CustomAutoMapperProfile));
使用
//获取Blognews数据实体
var blognew = await _blogNewsService.QueryAsync(pages, size, total);
//讲Blognews数据实体映射成BlogNewsDTO
var blognewsDTO = mapper.Map<List<BlogNewsDTO>>(blognew);