在此代码运行时,我无法移动或在我的UI中执行任何操作:
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),但我仍然无法移动表单。
编辑:也许我用错误的方法取回结果?
更新
在第一次回复(John's)之后,我尝试了这个:
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 ....表格冻结消失了,但是当任务结束时发生了异常
答案 0 :(得分:4)
这里有两个问题。
首先,您的代码试图从几乎可以肯定是不同的线程(即在任务中,可能在线程池线程中执行)访问UI线程。你不应该这样做。
其次,你在这里阻止了UI线程:
lblDescriptionValue.Text = itm.Result.Description;
访问itm.Result
属性将阻止,直到任务完成。您不希望这样做 - 这次在 UI线程中 - 因为这会冻结您的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());