当前位置: 首页 > news >正文

C#功能测试

List

内部元素为引用

src[0]的Name为"11",说明修改了引用

List<Source> src = new List<Source>();
src.Add(new Source() { Name = "1", Age = 1, Description = "1" });
src.Add(new Source() { Name = "2", Age = 2, Description = "2" });
foreach (var source in src)
{source.Name = "11";
}
Console.WriteLine(src[0].Name);

内部元素非引用

str[0]=“1”,说明修改的是副本

List<string> str = new List<string>();
str.Add("1");
str.Add("2");
for (int i =0;i >str.Count;i++)
{str[i] = "11";
}
Console.WriteLine(str[0]);

在这里插入图片描述

异步

wait()和await

  • 用wait()的话,进入任务后,任务会直接出不来
async void spin()
{while (true){ Task.Delay(1000).Wait();}  
}

在这里插入图片描述

  • 用await的话,进入任务后,会回到调用点
async void spin()
{while (true){ await Task.Delay(1000);}  
}

在这里插入图片描述

SemaphoreSlim

用于替换Lock,使用SemaphoreSlim可以在里面直接用await

SemaphoreSlim semaphore = new SemaphoreSlim(1, 1);
await test();
Console.WriteLine("done");async Task test()
{Task task1 = Task.Run(() => CriticalSection("Task 1"));Task task2 = Task.Run(() => CriticalSection("Task 2"));await Task.WhenAll(task1, task2);
}
async Task CriticalSection(string taskName)
{await semaphore.WaitAsync(); // 异步请求进入临界区  try{Console.WriteLine($"{taskName} 进入临界区.");// 模拟异步操作  await Task.Delay(1000);Console.WriteLine($"{taskName} 离开临界区.");}finally{semaphore.Release(); // 确保释放信号量  }
}

await

  • test会堵塞,可能因为这个是最后一个await
  • task1和task2由于semaphore的缘故,不会同时进,并且在Task.run的时候,就已经开始了
  • 在异步函数碰到await的时候,都会返回到调用方,等到await等待的任务体完成,这个异步函数才会往下执行
SemaphoreSlim semaphore = new SemaphoreSlim(1, 1);
await test();
Console.WriteLine("done");
async Task test()
{Task task1 = Task.Run(() => CriticalSection("Task 1"));Task task2 = Task.Run(() => CriticalSection("Task 2"));await Task.Delay(1000);var s = Stopwatch.StartNew();await Task.WhenAll(task1, task2);Console.WriteLine("when all done:" + s.ElapsedMilliseconds);
}
async Task CriticalSection(string taskName)
{await semaphore.WaitAsync();try{Console.WriteLine($"{taskName} 进入临界区.");await Task.Delay(2000);Console.WriteLine($"{taskName} 离开临界区.");}finally{semaphore.Release(); // 确保释放信号量  }
}

在这里插入图片描述

  • 把test()前的await去掉后,就不会堵塞,会直接执行done,然后到task1-2都完成了之后,输出when all done:3011,说明在异步函数碰到await的时候,都会返回到调用方(test),然后到输出done,等到await等待的任务体(WhenAll)完成,这个异步函数才会往下执行,输出when all done:3011
    在这里插入图片描述
  • 加上延时开始和延时结束日志,可以看出,开始在执行await Task.Delay(1000)后,就已经返回到调用方test了,输出done。等待1000ms延时结束后,再在test异步方法体里面往下执行,输出延时结束
    在这里插入图片描述

取消和超时取消

如果取消了,token.IsCancellationRequested会为真

// 创建 CancellationTokenSource  
var cts = new CancellationTokenSource();
// 设置超时时间为 5 秒  
cts.CancelAfter(TimeSpan.FromSeconds(5));
// 启动一个可以被取消的任务  
var task = Task.Run(() => DoWork(cts.Token), cts.Token);try
{await task;
}
catch (OperationCanceledException)
{Console.WriteLine("任务被取消(超时)。");
}static void DoWork(CancellationToken token)
{for (int i = 0; i < 10; i++){// 检查是否请求了取消  if (token.IsCancellationRequested){Console.WriteLine("请求取消,退出工作...");return;}Console.WriteLine($"工作中... {i}");Thread.Sleep(1000); // 模拟工作  }
}

http://www.mrgr.cn/news/91800.html

相关文章:

  • RabbitMQ 消息队列
  • AD(Altium Designer)三种方法导入图片
  • 超高清大图渲染性能优化实战:从页面卡死到流畅加载
  • three.js之特殊材质效果
  • 基于ffmpeg+openGL ES实现的视频编辑工具-opengl相关逻辑(五)
  • Http升级为Https - 开发/测试服环境
  • 保姆级! 本地部署DeepSeek-R1大模型 安装Ollama Api 后,Postman本地调用 deepseek
  • Hopper架构 GEMM教程
  • Debezium:实时数据捕获与同步的利器
  • 【飞行器原理学习】——1. 机翼及机翼参数
  • 【Python 专题】数据结构 树
  • 自动化之ansible(二)
  • Ecode在流程表单中插入自定义内容
  • 【鸿蒙笔记-基础篇_状态管理】
  • Debezium连接器对比
  • Python与Anaconda在CUDA环境中的角色解析
  • postcss.config.js 动态配置基准值
  • 【教学类-89-06】20250220新年篇05——元宵节灯笼
  • 【学习笔记】Cadence电子设计全流程(二)原理图库的创建与设计(1-4)
  • 毕业项目推荐:基于yolov8/yolov5/yolo11的果蔬检测识别系统(python+卷积神经网络)