2013-07-15 104 views
1

設置一個類的屬性,我填充了一些類屬性,在長時間運行的線程

其中之一涉及序列化的實體結構,以一個byte []這需要一些時間,所以我想這樣做在一個線程。

該值永遠不會被設置,因爲我認爲類和線程現在超出了範圍。

的代碼如下,任何想法,將不勝感激

public class classA 
{ 
    public void DoSomething() 
    { 
     var classC = new ClassB().DoSomethingElse(); 

     //SAVE CLASS c to database 
     var serialized = classC.GetSerializedDataTable(); // is always null unless i take out the task from class c 
    } 
} 

public class ClassB 
{ 
    public ClassC DoSomethingElse() 
    { 
     var classC = new ClassC(); 

     classC.DataTableValue = new DataTable(); 
     classC.SerializeToByteArray(); 
     return classC; 
    } 
} 

public class ClassC 
{ 
    public DataTable DataTableValue { get; set; } 
    private byte[] serializedData; 


    public void SerializedDataTable() 
    { 
     new Task(() => this.serializedData = this.DataTableValue.SerializeToByteArray()).Start(); 
    } 


    public byte[] GetSerializedDataTable() 
    { 
     return this.serializedData; 
    } 

} 
+2

相當多的代碼,但仍然是不完整。 –

+0

嗨亨克,是的,我只是做了這個僞代碼的例子,我的代碼比這更多,但基本上這給了我在做什麼的背景,基本上我開始了任務,當我試圖保存desirialized值時,它總是空的,可能是因爲任務和類已經超出了範圍?當我拿出任務時,它顯然有效... – MicroMan

+0

我不能說。僞造太多不好。你怎麼知道這個任務已經完成? –

回答

0

一個Task不僅僅意味着要使用另一個線程運行的代碼,它代表一個邏輯工作單元,可以返回的東西,一旦做完了。

ClassC.GetSerializedDataTable()似乎是利用一個Task<byte[]>返回類型的一個完美的地方:

public class ClassC 
{ 
    public DataTable DataTableValue { get; set; } 
    private Task<byte[]> serializeDataTask; 

    public void SerializeDataTable() 
    { 
     serializeDataTask = Task.Factory.StartNew(() => this.DataTableValue.SerializeToByteArray()); 
    } 

    public Task<byte[]> GetSerializedDataTable() 
    { 
     // You can either throw or start it lazily if SerializeDataTable hasnt been called yet. 
     if (serializeDataTask == null) 
      throw new InvalidOperationException(); 
     return serializeDataTask; 
    } 
} 

現在你的客戶端代碼可以利用智能方面的任務返回類型。如果結果已經可用,它可以通過Task.Result立即使用它。否則,它可以等待它完成,或者執行一些其他工作,直到完成。關鍵是調用代碼現在可以採取最合適的行動。

回到你的例子:

public void DoSomething() 
{ 
    var classC = new ClassB().DoSomethingElse(); 

    //SAVE CLASS c to database 
    var serializeTask = classC.GetSerializedDataTable(); 
    // will obtain result if available, will block current thread and wait for serialized data if task still running. 
    var serializedData = serializeTask.Result; 
}