![](/img/trans.png)
[英]Can I replace a call to await Task.Delay with an async method that has inside a await Task.Delay?
[英]How can I use Await Task.Delay without labeling all methods Async?
我正在替换基于线程的.NET 4.5基于任务的系统的旧代码。
我已经用Tasks替换了线程,接下来我正在用Await Task.Delay替换Thread.Sleep调用。 我遇到的问题是无法在Synclock部分中调用await,并且现在使用Await Task.Delay的每个方法都需要标记为Async。
我可能可以解决同步锁问题,因为我只有几个这样的块,可以用更好的代码代替。 但是,必须标记每个方法Async都会引起问题。 然后,这意味着我必须标记调用该方法Async的方法,依此类推。 最终,我所有的方法都将是异步的。
使用基于任务的方法时应该这样做吗?还是我做错了?
编辑1:发布示例代码
Public Async Function Delay(Milliseconds As Integer, Optional Initial As Boolean = False, Optional Silent As Boolean = False, Optional Modifier As Double = 0.3, _
Optional Task As Task = Nothing, Optional ExitOnTaskStop As Boolean = True) As Tasks.Task(Of Boolean)
Dim OutputBufferKey As String = Nothing
If Task IsNot Nothing Then
If Task.StopRequested Then Return True
OutputBufferKey = Task.OutputBufferKey
End If
If Initial Then
Milliseconds = Rand.Next(0, Milliseconds)
ElseIf Modifier > 0 Then
Dim MinValue As Integer = CInt(Milliseconds * (1 - Modifier))
Dim MaxValue As Integer = CInt(Milliseconds * (1 + Modifier))
If MinValue < MaxValue Then Milliseconds = Rand.Next(MinValue, MaxValue + 1)
End If
If DebugMode AndAlso Not Silent Then
Dim LengthString As String = Nothing
Select Case Milliseconds
Case Is < 60 * 1000 : LengthString = Math.Round(Milliseconds / 1000, 1) & " seconds"
Case Is < 60 * 60 * 1000 : LengthString = Math.Round(Milliseconds / (60 * 1000), 1) & " minutes"
Case Else : LengthString = Math.Round(Milliseconds / (60 * 60 * 1000), 1) & " hours"
End Select
Output(OutputBufferKey, "Sleeping for " & LengthString)
End If
If ExitOnTaskStop AndAlso Task IsNot Nothing Then
Try
Await Tasks.Task.Delay(Milliseconds, Task.CancellationToken.Token)
Catch ex As OperationCanceledException
Return True
End Try
Else
Await Tasks.Task.Delay(Milliseconds)
End If
Return False
End Function
由于许多原因,我需要延迟,并且该方法在其他许多方法中也被调用。 举几个例子,我有使用OpenPop DLL检查收件箱中是否有消息到达的代码,如果在第一次检查中不存在该消息,则需要再次检查之前我需要等待,如果没有,我将循环并进入睡眠状态已找到。 另一个示例是,我需要发出一个HttpWebRequest来检查文件,如果内容没有更改,我想在30秒内再次执行此操作。
我想使用计时器会是一个更好的主意? 如果是这样,Task.Delay的正确用法是什么?
您需要等待的方法应该标记为异步,而不是全部。 如果您有一个简单的函数添加Var1 + Var2
,则使该异步是荒谬的。 话虽这么说,您最终还是使很多事情变得不同步,因为它们调用的内容调用了需要等待的内容。
根据此处的讨论,使用计时器可能会更好,而计时器会导致另一个问题:“ Task.Delay的正确用法是什么?”? 我只使用它,所以我可以等待UI完成其工作。 例如,我调用一个数据库并启动UI转换,以便可能在接下来的1/2秒内逐渐显示屏幕的新部分。 我不想在那1/2秒内填写我的结果,因为它经常会产生抖动的画面,所以我等到完成为止。 最简单的方法是调用数据库,并创建一个延迟,然后使用WhenAll
等待最后一个完成。 这通常是我的1/2秒,但有时是数据库。
附带说明,您可以使用异步方法调用同步方法,该方法也将在后台运行。 这是从线程的转换要容易得多,但是由于您已经更改了大部分代码,所以您不想在这里使用它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.