c#整数在回调中作为引用传递
本文关键字:引用 整数 回调 | 更新日期: 2023-09-27 18:15:14
我有一点问题与回调和for循环,比如我有这样的代码
public void DoSth(Action<QueryTextureResult> result, IEnumerable<string> arr)
{
int totalData = 0;
foreach (var element in arr) // let's say arr.Count() is 10
{
Action<Texture> onImageReceived = (texture) =>
{
if (result != null)
{
var res = new QueryTextureResult()
{
Texture = texture,
QueryId = queryId,
Index = totalData // why this one is always 10 if the callback takes time?
};
result(res);
Debug.Log("INdex: " + res.Index);
}
};
imageManager.GetImage("http://image.url", onImageReceived);
totalData++;
}
}
如评论中所写,如果我有10个元素,调用result
需要时间,为什么我收到的QueryTextureResult.Index
总是10?它是通过引用传递的吗?有办法解决这个问题吗?
这是因为totalData
是封闭的,onImageReceived
将被异步调用。
假设你有3个项目,它可以按以下顺序执行:
-
onImageReceived
声明项目1,输出totalData
-
GetImage
被用于项目1 -
totalData = 1
-
onImageReceived
为项目2声明,输出totalData
-
GetImage
被用于项目2 -
totalData = 2
-
onImageReceived
为第3项声明,输出totalData
-
GetImage
被用于项目3 -
totalData = 3
- 项目1完成,调用
onImageReceived
事件,输出totalData
…现在是3 - 项目2完成,调用
onImageReceived
事件,totalData
也为3 - 第3项同
在您的代码示例中,捕获了totalData
,因此所有委托将引用相同的变量。在循环结束时,totalData
将具有10
的值,然后每个委托将读取相同的totalData
并将获得10
作为结果。
解决方案是在将变量传递给委托之前获取变量的副本,这样每个委托都有自己的副本。
foreach (var element in arr) // let's say arr.Count() is 10
{
var copy = totalData;
Action<Texture> onImageReceived = (texture) =>
{
if (result != null)
{
var res = new QueryTextureResult()
{
Texture = texture,
QueryId = queryId,
Index = copy // <==
};