2016-12-27 56 views
1

我有一段代碼循環訪問數組,其中數組元素存儲文件名。每循環,代碼加載一個XML文檔。當我直接調用數組元素時,我收到一個異常,說索引超出了數組的邊界,但是如果我將數組元素存儲到單獨的變量中,代碼編譯就好了。Dispatcher.BeginInvoke數組循環中的異常

我只是不明白爲什麼有差異,爲什麼一個工作,而不是其他。

編譯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); 
      })); 
    } 
} 
+0

你可以嘗試寫入控制檯的所有'我'值嗎? –

+0

你能證明你的'MyArray'是怎麼樣的 –

回答

2

的問題是由 「可變捕捉」 造成的,它使用的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); 
      })); 
    } 
} 
2

基本上這是已知的Captured變量行爲。它們是lambda表達式/語句所使用的外部變量。這些類型的lambda表達式/語句稱爲閉包。衆所周知,lambda表達式的執行有延遲。在執行時,它們使用捕獲變量的當前值而不是創建時的值。

爲了解決這個封閉問題,有一個通用的補救措施。無論何時我們需要在閉包中捕獲變量,我們都必須通過在lambda中聲明局部變量並將捕獲的變量的值分配給此局部變量來製作變量的本地副本。