[英]Dispatcher.BeginInvoke exception in an array loop
我有以下代碼遍歷數組,其中數組元素存儲文件名。 每個循環,代碼加載一個XML文檔。 當我直接調用數組元素時,我收到一個異常,指出index在數組的邊界之外,但是如果我將數組元素存儲到一個單獨的變量中,則代碼可以很好地編譯。
我只是不明白為什么會有區別,為什么一個起作用而另一個卻不起作用。
編譯OK
for(int i =0; i < MyArray.Count(); i++)
{
string myString = MyArray[i].Split(',')[0];
Dispatcher.BeginInvoke(new Action(() =>
{
string xmlPath = _PATH + + myString;
var document = XDocument.Load(xmlPath, LoadOptions.SetLineInfo);
}));
}
}
例外:索引超出數組的邊界
for(int i =0; i < MyArray.Count(); i++)
{
Dispatcher.BeginInvoke(new Action(() =>
{
string xmlPath = _PATH + + MyArray[i].Split(',')[0];
var document = XDocument.Load(xmlPath, LoadOptions.SetLineInfo);
}));
}
}
該問題是由“變量捕獲”引起的,它使用的是i
的最終值,而不是您調用它時的值。 要解決此問題,請在循環內部創建一個局部變量,然后改用該變量。
for(int i =0; i < MyArray.Count(); i++)
{
int j = i;
Dispatcher.BeginInvoke(new Action(() =>
{
string xmlPath = _PATH + + MyArray[j].Split(',')[0];
var document = XDocument.Load(xmlPath, LoadOptions.SetLineInfo);
}));
}
}
基本上,這是捕獲變量的已知行為。 它們是lambda表達式/語句使用的外部變量。 這些類型的lambda表達式/語句稱為Closures。 眾所周知,lambda表達式的執行會延遲。 在執行時,它們使用捕獲的變量的當前值,而不是創建它們時的值。
為了解決這種封閉問題,存在普遍的補救措施。 每當我們需要在閉包中捕獲變量時,都必須通過在lambda中聲明局部變量並將捕獲的變量的值分配給該局部變量來制作變量的局部副本。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.