2012-07-15 62 views
0

在下面的代碼,我試圖執行一個方法,它返回一個值,在另一個線程。但是,它只是不工作!多線程帶有Async給出了類型轉換誤差()

public void main() 
    { 
     lstChapters.DataContext = await TaskEx.WhenAll(LoadChapters()); 
    } 



    //CAN'T use async in this function, it requires Task<> which 
    //Error appears on the code inside [] 

    public [async Task<object>] Convert(object[] values, Type targetType, 
    object parameter, System.Globalization.CultureInfo culture) 
    { 
     dictChapters data = await IQ_LoadQuranXML.LoadChapters(TypeIndex); 
    } 




    internal static async Task< IEnumerable<dictChapters>> LoadChapters() 
    { 
     var element = XElement.Load("xml/chapters.xml"); 

     Task < IEnumerable <dictChapters>> something = (Task<IEnumerable<dictChapters>>) await TaskEx.Run(delegate 
     { 

     IEnumerable<dictChapters> Chapters = 
      from var in element.Descendants("chapter") 
      orderby var.Attribute("index").Value 
      select new dictChapters 
      { 
       ChapterIndex = Convert.ToInt32(var.Attribute("index").Value), 
       ChapterArabicName = var.Attribute("name").Value, 
       ChapterType = var.Attribute("type").Value, 
      }; 
      return Chapters;} 
     ); 

     return something; //An ERROR on this line 
    } 

    //Overriding method which does not return IEnumerable type. And it accepts index as integer. 
    internal static dictChapters LoadChapters(string chIdx = "0") 
    { 
     int chIdxInt = Convert.ToInt32(chIdx); 
     List<dictChapters> Chapters = (List<dictChapters>) LoadChapters(); // ERROR is on this line too 
     return Chapters.ElementAt(chIdxInt - 1); //index of chapter in the element starts from 0 
    } 

的錯誤是:

無法隱式轉換類型 'System.Threading.Tasks.Task<System.Collections.Generic.IEnumerable<iq_main.dictChapters>>' 到 'System.Collections.Generic.IEnumerable<iq_main.dictChapters>'。一個顯式轉換存在(是否缺少強制轉換?)

,另一個錯誤是..

無法將類型 'System.Threading.Tasks.Task<System.Collections.Generic.List<iq_main.dictChapters>>' 到'System.Collections.Generic.List<iq_main.dictChapters>

當我投「某事「明確地像return (IEnumerable<dictChapters>) something然後在運行時,我得到」InvalidCastException「。

+0

可能有人請告訴我的錯誤(或多個)的原因是什麼?也有是對答案的討論Stephen,我不明白Sync/Async的邏輯,當我按照Stephen的建議更改我的代碼時,出現另一個錯誤,此外,UI停止響應,進度條的活動不可見 – wafers 2012-07-15 10:55:17

回答

3

其實,你會得到比早先運行時投誤差。問題是你的演員TaskEx.Run結果。當你await東西,Task包裝被刪除。

public void main() 
{ 
    lstChapters.DataContext = await LoadChapters(); 
} 

internal static Task<List<dictChapters>> LoadChapters() 
{ 
    return TaskEx.Run(delegate 
    { 
    var element = XElement.Load("xml/chapters.xml"); 
    IEnumerable<dictChapters> Chapters = 
     from var in element.Descendants("chapter") 
     orderby var.Attribute("index").Value 
     select new dictChapters 
     { 
      ChapterIndex = Convert.ToInt32(var.Attribute("index").Value), 
      ChapterArabicName = var.Attribute("name").Value, 
      ChapterType = var.Attribute("type").Value, 
     }; 
    return Chapters.ToList(); 
    }); 
} 

您的代碼還有其他一些問題。請記住,像這樣的枚舉是懶惰執行的。您可能想要return Chapters.ToList();以便XML解析發生在線程池線程上。

+0

嗯,沒有任何改變。即使我返回章節.ToList()...它仍然需要很長時間來執行IEnumerable <>代碼塊。 – wafers 2012-07-15 00:52:44

+0

是的,它仍然抱怨TaskException – wafers 2012-07-15 00:53:32

+1

加載仍然是同步的(因爲它是在原始代碼) – 2012-07-15 00:59:16

1

既然你是在等待TaskEx.Run,​​你有枚舉回來,不是任務。

對於你在做什麼,我建議你只是保持LoadChapters爲正常/同步碼,然後要麼只是通過Task.Run調用它,或者把它原樣。

由於延遲執行,AFAICT當前的代碼並不能真正幫助任何事情,因爲你仍然在做負載同步。

的Task.WhenAll主可以刪除,只是等待LoadChapters(或任何異步方法是

+0

好的!我現在已經移除了等待並正常運行代碼。但是現在,用戶界面卡住仍然無響應或幾秒鐘,並且進度欄不顯示任何活動。 – wafers 2012-07-15 01:12:33