Visual Basic 异步任务而不是同步任务
Posted
技术标签:
【中文标题】Visual Basic 异步任务而不是同步任务【英文标题】:Visual Basic Async Task instead Sync Task 【发布时间】:2016-09-20 00:24:04 【问题描述】:我有一个执行同步任务的函数,我会做同样的事情,但使用异步任务。
我该怎么办?
这是代码:
Public Class Form1
Private taskOUT As Task
Private Sub Button_Start_Click(sender As Object, e As EventArgs) Handles 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
End Class
【问题讨论】:
请不要以图片形式发布您的代码。真的很难读,而且SO还有语法高亮功能…… 谢谢,我已经更正了。 【参考方案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 拆分为一个单独的函数,因为我没有您的库。不过,您可能可以将其编写为 lamda 函数。要取消任务,只需从取消按钮处理程序中调用 cancelSource.cancel。
可能不需要 uiSyncContext - 它只是确保当您的任务完成时,管道中的下一步将在 UI 线程上运行。如果您不这样做,而您尝试以某种方式更新 GUI,则会出现错误。
我们首先创建一个任务,该任务通过运行 gensin 函数返回一个双精度数组。然后我们附加一个写入输出的延续任务。仅当第一个任务正常完成时,后续任务才会运行。如果你取消了它,或者它抛出了一个错误,这将不会运行。您可以通过这种方式将一大堆任务链接在一起,并为成功/失败/取消结果提供不同的路由
【讨论】:
以上是关于Visual Basic 异步任务而不是同步任务的主要内容,如果未能解决你的问题,请参考以下文章