我在回调和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?它是通过参考传递的吗?有什么方法可以解决这个问题吗?
答案 0 :(得分:1)
在您的代码示例中,捕获了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 // <==
};
答案 1 :(得分:1)
这是因为totalData
已关闭,onImageReceived
将被异步调用。
假设您有3个项目,它可以按以下顺序执行:
onImageReceived
,输出totalData
GetImage
totalData = 1
onImageReceived
,输出totalData
GetImage
totalData = 2
onImageReceived
,输出totalData
GetImage
被称为第3项totalData = 3
onImageReceived
事件,该事件输出totalData
...现在是3 onImageReceived
个事件,totalData
也是3个