2016-05-23 25 views
0

私は同期タスクを実行する関数を持っていますが、私は同じですが非同期タスクを使用します。Visual Basic非同期タスク代わりに同期タスク

どうすればよいですか?

これはコードです:

パブリック・クラスのForm1 タスク

としてプライベートtaskOUTプライベートサブButton_Start_Click(オブジェクト、EventArgsのようEと、送信者が)Button_Start.Click

Dim freq As Double = TextBox1.Text 
    Dim Amp As Double = TextBox2.Text 
    Dim SPB As Double = TextBox3.Text 
    Dim CPB As Double = TextBox4.Text 
    '--------------------------------------- 
    Dim SCRate As Double = (freq * SPB)/CPB 
    '--------------------------------------- 
    taskOUT = New Task() 'Crea un task 
    taskOUT.AOChannels.CreateVoltageChannel("Dev1/ao0", "", -10, 10, AOVoltageUnits.Volts) 'Aggiunge un canale in Out 
    taskOUT.Timing.SampleClockRate = SCRate 
    taskOUT.Timing.ConfigureSampleClock("", SCRate, SampleClockActiveEdge.Rising, SampleQuantityMode.ContinuousSamples, 1000) 
    '----------------------------- 
    Dim ydata As Double() 
    ydata = GenSin(freq, Amp, SCRate, SPB) 
    '------------------------------------------- 
    Dim writer As New AnalogSingleChannelWriter(taskOUT.Stream) 
    writer.WriteMultiSample(False, ydata) 
    taskOUT.Start() 
End Sub 
'----------------------------------------------------------------------- 
Public Shared Function GenSin(_ 
    ByVal freq As Double, _ 
    ByVal amp As Double, _ 
    ByVal sampleClockRate As Double, _ 
    ByVal samplePerBuffer As Double) As Double() 

    Dim dt As Double 
    Dim IntSample As Integer 

    dt = 1/sampleClockRate 
    IntSample = CInt(SamplePerBuffer) - 1 
    Dim y(IntSample - 1) As Double 
    For i As Integer = 0 To IntSample - 1 
     y(i) = amp * Math.Sin((2.0 * Math.PI) * freq * (i * dt)) 
    Next 
    Return y 
End Function 

Private Sub Button_Stop_Click(sender As Object, e As EventArgs) Handles Button_Stop.Click 
    taskOUT.Stop() 
    taskOUT.Dispose() 
End Sub 

エンドクラスを処理します

+0

コードを画像としてではなく、ポストしてください。それは本当に読みにくいですし、SOには構文を強調表示する機能があります... –

+0

ありがとう、私は訂正しました。 –

答えて

1

次のようなものがあります。

Private cancelSource As CancellationTokenSource 

Sub StartWork 
     cancelSource = New CancellationTokenSource 
     Dim uiSyncContext = Tasks.TaskScheduler.FromCurrentSynchronizationContext 
     Dim task = New Tasks.Task(Of Double())(Function() GenSin(3.4, 1.2, 100.0, 1000.0, cancelSource.Token)) 
     task.ContinueWith(Sub(dt) WriteData(dt.result), 
          cancelToken, 
          Tasks.TaskContinuationOptions.OnlyOnRanToCompletion, 
          uiSyncContext) 
    End Sub 

    Function GenSin(freq As Double, amp As Double, rate As Double, spb As Double, cancelToken As CancellationToken) As Double() 
     Dim dt As Double 
     Dim isamp As Integer 
     dt = 1/rate 
     isamp = CInt(spb) - 1 
     Dim y(isamp - 1) As Double 
     For i As Integer = 0 To isamp - 1 
      If cancelToken.IsCancellationRequested Then Return Nothing 
      y(i) = amp * Math.Sin(2 * Math.PI * freq * i * dt) 
     Next 
     Return y 
    End Function 

    Sub WriteData(results As Double()) 
     ' This is where you output the data 
    End Sub 

ライブラリを持たないため、WriteDataを別の関数に分割しました。あなたはおそらくラムダ関数としてそれを書くことができます。タスクをキャンセルするには、キャンセルボタンハンドラからcancelSource.cancelを呼び出します。

uiSyncContextは必要ないかもしれません。タスクが完了したら、パイプラインの次のステップがUIスレッド上で実行されることを確認するだけです。これを行わずに、何らかの方法でGUIを更新しようとすると、エラーが発生します。

まず、gensin関数を実行してdouble型の配列を返すタスクを作成します。次に、出力を書き込む続行タスクを追加します。継続タスクは、最初のタスクが正常に完了した場合にのみ実行されます。キャンセルした場合、またはエラーが発生した場合、これは実行されません。成功/失敗/キャンセルの結果のための別個のルーティングを使用して、この方法で一連のタスクを連鎖させることができます