欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 房产 > 建筑 > C#功能测试

C#功能测试

2025/2/21 17:30:37 来源:https://blog.csdn.net/weixin_41303851/article/details/145679076  浏览:    关键词: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); // 模拟工作  }
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词