2016-06-29 2 views
2

私はタスクで小さな問題を抱えています..以下は、私がやっていることの簡単な例のスクリーンショットです。私はThirdJobが最初に表示され、次にSecondJob、そしてFirstJob(またはそれが何であっても)を表示します。タスクは、私がそれらを必要とする順序で来ていません

enter image description here

私は、ドロップダウンボックスをクリックし、そしてそれは、私がボタンを押すと、それは(仕事の)リストに基づいて、これらのタスクを実行... listbox1をにタスクを追加します。

私はThirdJobに1000 MSの遅延を持っています。もちろん、それは最後に来ます。どれくらい時間がかかっても、彼らが望む順序で来るようにするにはどうしたらいいですか?私はこれを行うために使用してい

現在のコード..

Dim tasklist As New List(Of Task) 

Private Async Sub Button_Click(sender As Object, e As RoutedEventArgs) 

    For Each item In tasklist 
     'item.RunSynchronously() 
     item.Start() 
    Next 

    Await Task.WhenAll(tasklist.ToArray) 

End Sub 

Public Sub FirstJob() 
    Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background, DirectCast(Function() listbox2.Items.Add("FirstJob"), Action)) 
End Sub 
Public Sub SecondJob() 
    Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background, DirectCast(Function() listbox2.Items.Add("SecondJob"), Action)) 
End Sub 
Public Sub ThirdJob() 
    Thread.Sleep(1000) 
    Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background, DirectCast(Function() listbox2.Items.Add("ThirdJob"), Action)) 
End Sub 

Private Sub ComboBox_SelectionChanged(sender As Object, e As SelectionChangedEventArgs) 

    listbox1.Items.Add(cb1.SelectedItem) 
    If cb1.SelectedItem.ToString = "FirstJob" Then 
     tasklist.Add(New Task(Sub() FirstJob())) 
    ElseIf cb1.SelectedItem.ToString = "SecondJob" Then 
     tasklist.Add(New Task(Sub() SecondJob())) 
    ElseIf cb1.SelectedItem.ToString = "ThirdJob" Then 
     tasklist.Add(New Task(Sub() ThirdJob())) 
    End If 

End Sub 

Private Sub MainWindow_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded 
    cb1.Items.Add("FirstJob") 
    cb1.Items.Add("SecondJob") 
    cb1.Items.Add("ThirdJob") 
End Sub 

は、私は問題は、私は私の配列しかしループのための私のやっている方法であると確信しています。

私はそれがために行くが、私はしたくないUIを、フリーズ

For Each item In tasklist 
    item.Start() 
Next 

Await Task.WhenAll(tasklist.ToArray) 

For Each item In tasklist 
    item.Start() 
    item.wait 
Next 

に変更した場合。何か案は?

+0

あなたはそれが一覧であれば、それにソートを行う 'tasklist'を注文する必要があります順番に聞こえますあなたはデバッガを使ってコードをステップ実行し、 'item'を評価したことがありますか? – MethodMan

+3

ここで私の好きな曲のうち、「緑がかわいい女の子たちと並んでいる同時性都市に連れて行こう」というものがあります。 – Enigmativity

+0

@Enigmativity Clever +1 – TonyW

答えて

1

カスタムメソッドを作成し、Task.ContinueWith()メソッドを使用して相互にタスクを開始する方法はありますか?

Public Class TaskHelper 
    Public Shared Function RunAllSequential(ByVal Tasks() As Task) As Task 
     For i = 0 To Tasks.Length - 2 'Using -2 since the last task don't need to start another one. 
      Dim j As Integer = i 
      Tasks(i).ContinueWith(Sub() Tasks(j + 1).Start()) 
     Next 

     Tasks(0).Start() 'Start the first task. 

     Return Task.WhenAll(Tasks) 
    End Sub 
End Class 

これは、指定されたタスクを互いに実行します。最初のものが完了すると、2番目のものが開始されます。

使用例:あなたがそれらをしたい場合は、バックグラウンドワーカーを必要とするよう

Await TaskHelper.RunAllSequential(tasklist.ToArray()) 
+1

私は私の電話からこれを書いたことに注意してください。私はまだそれをテストしていない。だから問題が発生した場合は教えてください。 –

+0

私は家に帰るとすぐにこれをチェックします、ありがとうございます。それは2または3のリスト、または20かもしれません。私はリストの長さを取得し、最初の項目以外のすべてを取り除く必要があると仮定します。 – TonyW

+1

@トニーW:いいえ、何も取り除く必要はありません。上記のようにリストを配列に変換するだけです。私のコードは次のようになります:** 1)**各タスクを(最後のものを除いて) 'ContinueWith()'に設定して次のタスクを開始します。 ** 2)**最初のタスクのみを開始します。 ** 3)**配列として配列をパラメータとして 'Task.WhenAll()'を呼び出し、結果のタスクを返します。 - 文字通り、私のクラスをコピーしてコードをコピーするだけで、 'Await Task.WhenAll(tasklist.ToArray)'を 'Await TaskHelper.RunAllSequential(tasklist.ToArray())'に変更することができます。 –

関連する問題