2012-12-02 34 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