0

長時間実行するタスク(基本的にはネットワークからの読み取り)を実行する必要があるWPFアプリケーションがあります。スナップショットを提供するために、ボタンクリックで次のことを行っています

 Dim t As Task(Of String) = Task.Factory.StartNew(Of String)(Function()
                                                                        'Thread.sleep is simulating long running task that will make UI unresponsive
                                                                        Thread.Sleep(10000)
                                                                        Return "Hello world from async task"
                                                                    End Function)

        TextBlock1.Text = t.Result

読み取りAPIは、プログラムで参照するdllに実際に存在し、関数が含まれているため、イベントベースの非同期手法を使用できませんPublic function ReadFromNetwork() as String。このAPIは、ネットワークを非同期呼び出しして、長い文字列を読み取り、UIに戻ります。だから、要するに私はやっていTextBlock1.Text = ExternalDll.ReadFromNetwork()ます。

しかし、問題は、タスクの非同期を使用しても、UIが応答しないことです。

コードに何かが欠けているかどうかを検出してください。

どんな助け/提案も前もって感謝されますThanx

4

3 に答える 3

8

t.Resultタスクを開始した後、オンラインで使用しています。これにより、タスクが完了するまでスレッドがブロックされるため、すべての非同期性が無駄になります。

を使用して継続をアタッチTask.ContinueWithし、タスクの結果を使用するコードをその継続に配置する必要があります。これにより、UI はタスクの実行中にイベントの処理に戻ることができ、タスクが完了すると継続が開始されます。TaskScheduler.FromCurrentSynchronizationContext継続が正しいスレッドで発生することを確認するために渡します。

VB/C# の次のバージョンでは、これらすべてがasync メソッドを使用してはるかに簡単になることに注意してください。.NET 4.5 リリース候補を使用できる場合は、今すぐこれを試してみることを検討してください。そうすれば、作業がずっと簡単になります。

于 2012-06-14T06:21:29.067 に答える
2

t.Resultタスクを強制的に実行するように呼び出しています。ContinueWith結果を非同期で取得するには、を使用する必要があります。

    var action = delegate(Task<string> s)  // to avoid cross thread exception 
        {
            Action ac = delegate() { TextBlock1.Text = s.Result; };
            this.Dispatcher.Invoke(ac);

        };

      t.ContinueWith(action);

c#を使用してすみません

于 2012-06-14T06:27:51.500 に答える
1

私はそれが次のようなものであるべきだと思います

t.ContinueWith((result) => { TextBlock1.Text = result.Result});

それとも、投稿中に紛失しただけですか?これがトリックを行うことを除いて、正しいスケジューラを使用する必要があるかもしれません

于 2012-06-14T06:21:21.330 に答える