1

当这段代码运行时,我不能在我的 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) 但我仍然无法移动表单。

编辑:也许我使用错误的方式来取回结果?

更新:

在第一次回复(约翰的)之后,我尝试了这个:

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();
});

但是我当然又在弄乱用户界面了....表单冻结消失了,但是当任务完成时发生了异常

4

1 回答 1

5

这里有两个问题。

首先,您的代码试图从几乎可以肯定是不同的线程(即在任务中,这可能会在线程池线程中执行)访问 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());
于 2012-12-02T20:47:59.107 回答