gpt4 book ai didi

C# 将字符串元素数组传递给 Task.Run

转载 作者:太空宇宙 更新时间:2023-11-03 20:53:52 26 4
gpt4 key购买 nike

尝试将字符串数组的一个元素传递给在 Task.Run 中调用的函数。有人知道这里的错误是什么吗?

此处的代码不起作用,它的行为就好像 ProcessElem 从未被调用过一样。

string[] arr = message.Split(new string[] {"\n"}, StringSplitOptions.None);

for (int i = 0; i < arr.Length; i++) {
if(arr[i] != "") {
var t = Task.Run(() => this.ProcessElem(arr[i]));
}
}

但是下面的代码有效

string[] arr = message.Split(new string[] {"\n"}, StringSplitOptions.None);

for (int i = 0; i < arr.Length; i++) {
if(arr[i] != "") {
var tmp = arr[i];
var t = Task.Run(() => this.ProcessElem(tmp));
}
}

我对 C# 的处理方式还很陌生,但这两种模式似乎都不安全,因为调用 Task.Run() 的函数可能会在 ProcessElem 函数执行之前返回,如果字符串是通过引用传递的,那么它们将在调用 ProcessElem 之前销毁。

如果是这种情况,将字符串传递到 ProcessElem 的最佳方法是什么?

另外,为什么第一个版本实际上没有“调用”ProcessElem?我在 ProcessElem 的顶部有一个打印语句,它只在第二个版本中打印。

最佳答案

欢迎来到captured variables .

Task.Run(() => this.ProcessElem(arr[i]))

这基本上意味着:

  1. 执行我的 lambda 操作:() => this.ProcessElem(arr[i])

  2. 在找到/创建线程后运行它。 一段时间后

但是,只涉及一个变量,i,它是在您的 lambda 操作范围之外定义的,它不会被复制,相同 变量只是 捕获并引用。

当线程开始执行时,i 的值很可能已经改变。通常,循环在线程执行其工作之前结束。

这意味着到那时,i 等于 arr.Length 并且所有线程都尝试访问 arr[arr.length],这显然导致 IndexOutOfRangeException

当您执行 var tmp = arr[i]; 时,您将在每次循环迭代中创建一个新变量,复制循环变量并在您的 lambda 中捕获该副本,这就是它起作用的原因。

关于C# 将字符串元素数组传递给 Task.Run,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52573555/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com