1

このコードの実行中、UIを移動したり、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();
});

しかしもちろん、私は再びuiを台無しにしています....フォームのフリーズはなくなりましたが、タスクが終了すると例外が発生しました

4

1 に答える 1

5

ここには2つの問題があります。

まず、コードはほぼ確実に別のスレッドから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 に答える