2012-12-02 36 views
1

儘管此代碼運行時我不能移動或在我的UI做任何事情:Task.StartNew保持主線程,同時運行

var a = txtLot.Text; 
var b = cmbMcu.SelectedItem.ToString(); 
var c = cmbLocn.SelectedItem.ToString(); 

var itm = Task<JDEItemLotAvailability> 
.Factory.StartNew(() => 
{ 
     btnCheck.BackColor = Color.Red; 
     var ret = Dal.GetLotAvailabilityF41021(a, b, c); 
     btnCheck.BackColor = Color.Transparent; 
     return ret; 
} 
    ); 
lblDescriptionValue.Text = itm.Result.Description; 
lblItemCodeValue.Text = itm.Result.Code; 
lblQuantityValue.Text = itm.Result.AvailableQuantity.ToString(); 

我試圖講評調用DAL方法,並把Thread.sleep代碼( 5000),但我仍然無法移動表格。

編輯:也許我用錯誤的方式來取回結果?

UPDATE:

第一應答(約翰)我想在此之後:

var a = txtLot.Text; 
var b = cmbMcu.SelectedItem.ToString(); 
var c = cmbLocn.SelectedItem.ToString(); 

var itm = Task<JDEItemLotAvailability> 
.Factory.StartNew(() => 
{ 
     btnCheck.BackColor = Color.Red; 
     var ret = Dal.GetLotAvailabilityF41021(a, b, c); 
     btnCheck.BackColor = Color.Transparent; 
     return ret; 
} 
    ).ContinueWith(itm => 
{ 
lblDescriptionValue.Text = itm.Result.Description; 
lblItemCodeValue.Text = itm.Result.Code; 
lblQuantityValue.Text = itm.Result.AvailableQuantity.ToString(); 
}); 

,但當然我又搞亂UI ....形式凍結走了,但是當任務完成異常發生

回答

4

這裏有兩個問題。

首先,你的代碼試圖從幾乎可以肯定是不同的線程(即在任務中,這可能會在線程池線程中執行)訪問UI線程。你不應該那樣做。

其次,你在這裏阻塞UI線程:

lblDescriptionValue.Text = itm.Result.Description; 

訪問itm.Result屬性將,直到任務完成。你不想這樣做 - 這一次 UI線程 - 因爲這將凍結你的用戶界面,正如你所觀察到的。

如果您使用的是C#5和.NET 4.5,那麼您可以嘗試使用新的異步功能 - 這可能會使更容易做到您想要的功能。

如果您不能使用.NET 4.5(或.NET 4的異步定位包),則應使用Task.ContinueWith告知Task完成後您想要執行的操作。

編輯:我懷疑你想要的東西,如:

var a = txtLot.Text; 
var b = cmbMcu.SelectedItem.ToString(); 
var c = cmbLocn.SelectedItem.ToString(); 

btnCheck.BackColor = Color.Red; 
var task = Task.Factory.StartNew(() => Dal.GetLotAvailabilityF41021(a, b, c)); 
task.ContinueWith(t => 
{ 
    btnCheck.BackColor = Color.Transparent; 
    lblDescriptionValue.Text = t.Result.Description; 
    lblItemCodeValue.Text = t.Result.Code; 
    lblQuantityValue.Text = t.Result.AvailableQuantity.ToString(); 
}, TaskScheduler.FromCurrentSynchronizationContext()); 
+0

我明白了,我不能使用4.5,因爲我需要的應用程序對一些XP的機器上運行,所以我會堅持使用Task類。你能告訴我更多關於如何從代碼中刪除任何UI元素並使用continuewith?我嘗試使用它,但我仍然收到錯誤..(我正在更新第二次嘗試 – e4rthdog

+0

呃,首先你要做的是將背景顏色設置爲紅色 - 所以在開始任務前就這樣做。可以在完成時將其設置爲透明,我將使用一些示例代碼進行編輯 –

+0

謝謝,如果您能展示我將與ContinueWith做什麼(結果是我的意思)謝謝 – e4rthdog