我在HTTPHandler中有一个长时间运行的进程,我使用Async Await .net 4.5异步执行

这完美按预期工作......

如何添加超时,以便在进程耗时太长时返回字符串'timeout'?

Protected Async Sub button1_Click(sender As Object, e As System.EventArgs)
    Dim asyncHandler = New AsyncHandler
    Await asyncHandler.ProcessRequestAsync(HttpContext.Current)
    Response.Write(asyncHandler.Result)
End Sub

Public Class AsyncHandler
    Inherits HttpTaskAsyncHandler

    Public Property Result As String

    Public Async Function ProcessRequestAsync(context As HttpContext) As Task
        Me.Result = Await DoLongRunningProcessAsync(context)
    End Function

    Private Function DoLongRunningProcessAsync(context As HttpContext) As Task(Of String)

        'TODO: add a timeout so that if this takes too long we return "timeout":

        Return Task.Run(Of String)(Function() DoLongRunningProcess(context))

    End Function

    Private Function DoLongRunningProcess(context As HttpContext) As String
        'perform long running process....

        Return "success"
    End Function

End Class

===============>>#1 票数:4 已采纳

这是我最终实现的:

创建一个具有超时值x毫秒的CancellationToken

添加了一个try catch来捕获错误:OperationCanceledException

Public Async Function ProcessRequestAsync(context As HttpContext) As Task
        Dim cts As CancellationTokenSource = New CancellationTokenSource(30000) 'eg: 30 seconds
        Try
            Me.ResultCode = Await DoLongRunningProcessAsync(HttpContext.Current, cts.Token)
        Catch ex As OperationCanceledException
            Me.ResultCode = "timeout"
        End Try
End Function

将CancellationToken传递给DoLongRunningProcessAsync方法的签名

通过调用ThrowIfCancellationRequested来检测超时

Private Function DoLongRunningProcessAsync(context As HttpContext, ct As CancellationToken) As Task(Of String)
        Return Await Task.Run(Of String)(
            Function()
                Dim resultCode As String = DoLongRunningProcess(context)

                'detect timeout:
                ct.ThrowIfCancellationRequested()

                Return resultCode
            End Function)
End Function

这是一篇很棒的文章,我发现它确实有帮助:

4.5中的异步:在异步API中启用进度和取消

===============>>#2 票数:2

我不打结VB.NET,但我通常在C#中这样做,如下例所示:

CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();

// Make sure that we have a way to cancell long running 
Task<SomeClass> longRunningTask = GetSomethingAsync(cancellationTokenSource.Token);

// One of the task should be finished
if (longRunningTask == await Task.WhenAny(longRunningTask, Task.Delay(30000)))
{
     // Long running task completed
     SomeClass result = await longRunningTask;
}
else
{
     // Task.Delay(30000) was finished
     cancellationTokenSource.Cancel();
}

===============>>#3 票数:0

通常,支持超时的TPL代码通过@outcoldman和@StephenCleary提到的CancellationToken(Source)来实现。 但是,在您的方案中,您说您希望超时路径也返回一个字符串,只是另一个字符串。

因此,不是使用CancellationToken(Source),而是将超时代码视为生成字符串的另一个任务,然后选择任何一个任务(超时任务或“实际”任务)完成并返回该字符串可能更简单。

我将您的DoLongRunningProcess(最里面的函数)更改为异步并返回Task(Of String),这样您就不必使用Task.Run了。

'Await Await'可能看起来很奇怪,但Task.WhenAny返回一个Task(Of Task(Of T)),所以第一个Await是到达先完成的特定任务,然后我们等待它以获得实际字符串结果。

Sub Main
    MainAsync().Wait()
End Sub

' Define other methods and classes here
Public Async Function MainAsync As Task
    Dim asyncHandler = New AsyncHandler
    Await asyncHandler.ProcessRequestAsync(System.Web.HttpContext.Current)
    Console.WriteLine(asyncHandler.Result)
End Function

Public Class AsyncHandler
    Inherits HttpTaskAsyncHandler

    Public Property Timeout As TimeSpan = TimeSpan.FromSeconds(10)

    Public Property Result As String

    Public Overrides Async Function ProcessRequestAsync(context As HttpContext) As Task
        Me.Result = Await DoLongRunningProcessAsync(context)
    End Function

    Private Async Function DoLongRunningProcessAsync(context As HttpContext) As Task(Of String)

        'TODO: add a timeout so that if this takes too long we return "timeout":

        Dim workerTask As Task(Of String) = DoLongRunningProcess(context)
        Dim cancelTask As Task(Of String) = DoTimeout()

        Return Await Await Task.WhenAny(workerTask, cancelTask)

    End Function

    Private Async Function DoTimeout() As Task(Of String)
        Await Task.Delay(Timeout)

        Return "timeout"
    End Function

    Private Async Function DoLongRunningProcess(context As HttpContext) As Task(Of String)
        'perform long running process....

        Await Task.Delay(TimeSpan.FromSeconds(15))

        Return "success"
    End Function

End Class

  ask by George Filippakos translate from so

未解决问题?本站智能推荐:

2回复

了解多个条件任务何时完成的最佳.net 4.5异步方法?

我有一个从电子邮件标题中提取值的函数。 为了加快速度,想要使用框架4.5中的异步。 这是我第一次使用异步。 我连续多次异步调用提取函数以提取不同的值。 从电子邮件标题中。 我遇到的麻烦是如何知道所有实例何时完成。 我发现了一些示例,但没有找到适合我的条件任务的示例。 我相信
1回复

使用asnet / await和.net 4.5对HttpResponse进行多次小写操作的正确方法

我正在尝试将我的HTTP响应实现为完全异步 (使用async / await)。 这是一个很好的简化,但我们假设我需要做多个小写: 例如,一个用例是将对象手动编码为JSON或XML,并在对象遍历期间遇到它时将每个对象写入响应。 我目前的实施是: 这是正确的方法吗?
1回复

进行异步处理时,CurrentModuleContainer.Get Asp .Net代码中偶尔出现NullPointerException

我有一个Asp .Net应用程序,正在使用带有.net 4.5 RC的新async / await范例。 我正在使用新的基于任务的异步http处理程序HttpTaskAsyncHandler来处理http请求。 在我的代码中,我正在执行一些将文件流式传输到客户端的I / O。 偶尔我会
1回复

异步的会话状态意外行为

我正在研究async并在ASP.NET MVC控制器方法的上下文中await ,并且得到了一些意外的行为。 我有以下控制器类: 以及每种方法Check1和Check2的简单视图: 检查1 检查2 现在,在启动应用程序后,立即在一个选项卡中打开http://lo
1回复

使用vb返回IEnumerable时,Asp.net 4.5模型绑定被破坏了吗?

我有一个gridview如下: 我在c#中有以下代码可行: 现在,在VB中我有: VB版本始终生成以下错误: 当DataBoundControl启用了分页时,SelectMethod应返回IQueryable或应具有所有这些必需参数:int startRowIn
1回复

将迭代转换为异步

我将返回大量的DataTable行,对其进行迭代并将每行的值推送到Web服务,然后该Web服务将返回响应代码(字符串)。 如果Web服务中发生任何错误,则整个过程将停止并显示错误: 我认为上述方法是异步方法的理想选择,特别是如果数据表有1000行,因为每个Web服务请求都可以并行发送。
1回复

超时后如何取消异步WebApi操作?

使用ASP.Net WebAPI,我有一个控制器,其异步操作类似于以下内容: 这个控制器的作用并不重要。 重要的是它正在等待使用新的.net 4.5 async / await支持的异步任务。 问题:如何在指定的持续时间后告诉它超时? 我不一定要取消任务,我只是想阻止来电者永远
1回复

简单的ASP.NET 4.5异步并在VB.NET中等待

我试图得到一个简单的异步示例等待工作,但我认为不是。 我认为这段代码需要花费10秒钟(或超过10秒钟)来运行,因为每个循环中的每个函数都应该异步运行。 这是一个asp.net Web表单,Async =“true”出现在页面声明中。 提前致谢!
2回复

将异步等待集成到同步方法中

我一直在撞墙挡住了两天,坦率地说,我对自己很生气,因为我似乎无法得到它 。 我在webapi环境中。 在此请求期间,我需要将一些数据发送到我们的其他系统之一,由于计算量大和多次数据库保存等原因,此系统返回速度很慢。我需要记录此操作的结果,无论它是否成功或不。 但我不想等待它完成。
1回复

如何使用异步/等待模式同步共享资源

这个问题已经在这里有了答案: 如何保护可能在多线程或异步环境中使用的资源? 1个答案 我正在开发一些实质上是发布/订阅框架的软件。 订阅时,我必须保留要订阅的内容的记录,并且需要同时进行订阅和取消订阅的原子操作。 连接由GUID标识,并且可以具有多个订阅(