Task.StartNew保持主线程,同时运行
问题描述:
尽管此代码运行时我不能移动或在我的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 ....形式冻结走了,但是当任务完成异常发生
答
这里有两个问题。
首先,你的代码试图从几乎可以肯定是不同的线程(即在任务中,这可能会在线程池线程中执行)访问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());
我明白了,我不能使用4.5,因为我需要的应用程序对一些XP的机器上运行,所以我会坚持使用Task类。你能告诉我更多关于如何从代码中删除任何UI元素并使用continuewith?我尝试使用它,但我仍然收到错误..(我正在更新第二次尝试 – e4rthdog
呃,首先你要做的是将背景颜色设置为红色 - 所以在开始任务前就这样做。可以在完成时将其设置为透明,我将使用一些示例代码进行编辑 –
谢谢,如果您能展示我将与ContinueWith做什么(结果是我的意思)谢谢 – e4rthdog