在异步方法上调用RegisterAsyncTask [英] Calling RegisterAsyncTask on an async method

查看:35
本文介绍了在异步方法上调用RegisterAsyncTask的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我发布了先前的问题( asp.net带有UserControls和页面级异步方法的UpdatePanel ),并认为我已将问题缩小为一个单独的问题.

I posted a previous problem (asp.net UpdatePanel with UserControls and Page Level Async Method), and think I have narrowed down my issue to a separate question.

我有一个asp.net页面,该页面需要从库中调用异步方法.

I have an asp.net page, which needs to call an async method from a library.

我将页面加载如下:

Private _dlgt As AsyncTaskDelegate
Protected Delegate Sub AsyncTaskDelegate()

 Protected Sub Page_Load(ByVal sender As Object, ByVal e As 
    Dim LoadTask As New PageAsyncTask(AddressOf OnBegin, AddressOf OnEnd, AddressOf OnTimeout, "AsyncTask1", True)
    Page.RegisterAsyncTask(LoadTask)
End Sub

Public Function OnBegin(ByVal sender As Object, ByVal e As EventArgs, ByVal cb As AsyncCallback, ByVal extraData As Object) As IAsyncResult
    _dlgt = New AsyncTaskDelegate(AddressOf Update)
    Dim result As IAsyncResult = _dlgt.BeginInvoke(cb, extraData)
    Return result
End Function

Private Async Function Update() As Task
    Dim AController As New CIP_WS.ARFController
    Dim ARFTask As Task(Of CIP_WS.ARF) = AController.GetARFWithResultsAsync(Client.ClientID, PRN, Nothing, StartTime, EndTime, CIP_WS.LabResultController.InequalityModes.AsIs)
    ARF = Await ARFTask
    PrintResults()
End Function

问题(我认为)是,我必须将page属性设置为async = true,因为我需要等待任务.但是(根据MS),如果我将属性设置为true,则整个页面将被异步处理.如果设置为false,则将阻止执行页面的线程,直到所有异步任务完成为止".后者是我需要的,因为它正在加载和显示页面,即在数据之前(即在更新异步方法返回之前),而我仅获得占位符.

The problem (I think), is that I have to set the page attribute to async=true, as I need to await a task. However (according to MS), if i set the attribute to true, the whole page will be processed asynchronously. If set to false, "the thread that executes the page will be blocked until all asynchronous tasks are complete". The latter is what I need, as it is loading and displaying the page, before the data (i.e before the update async method returns), and I am only getting placeholders.

要清楚,Update方法永远不会完成.Page_Load总是完成而无需等待方法完成.

To be clear, the Update method never completes. The Page_Load always complete without await the method to finish.

我感觉很亲密,但是现在要让它开始工作还很遥远.任何帮助,万分感谢.

I feel so close, but far on getting this to work now. Any help, much appreciated.

EDIT ____

EDIT____

首先感谢您到目前为止的答复.

Firstly thanks for the responses so far.

我以前尝试过以下代码,并且90%都能正常工作,但是感谢您的建议.

I have tried the following code previously and it 90% works, but thanks for the suggestion.

    Dim LoadTask As New PageAsyncTask(AddressOf Update)
    Page.RegisterAsyncTask(LoadTask)

这可能是我自己的错,但我一直在尝试使问题更简单,但问题不止于此.

It is probably my own fault, but I have been trying to keep the problem simple, but it is bigger than this.

只有90%以上的代码有效,因为它可以很好地异步加载数据,然后页面按预期方式呈现和加载.但是,我有一些动态的用户控件,这些控件最初也可以很好地加载,但是在回发期间无法正确运行.在这种情况下,当用户单击按钮时,它不会更改特定用户控件内面板的可见性.我已经在上面提到的另一个SO问题的链接上完整记录了该问题,但是总之,当我不使用异步时,它工作正常,但是在加载过程中进行异步调用时,效果很好.

The code above only 90% works, because it loads the data async fine, and then the page renders and loads as expected. However, I have some dynamic user-controls, which also load fine initially, but do not behave correctly during postbacks. In this case, when a user click a button, it does not change the visibility of a panel within the specific user-control. I have fully documented the issue on the link to another SO question above, but in short it works fine when I do not use async, but not when I have an async call during load.

我继续进行该项目的另一部分,与此同时我休息了一下,开始异步处理该站点的另一部分.同样,我点击了更多动态用户控件,但是这次异步调用是在用户控件而不是页面的负载中.我遇到了完全相同的问题,只是下拉菜单没有保留选择,而不是面板可见性没有保留.我发现我需要通过以下方式调用asyn方法

I moved on to another part of the project , while I took a break from that problem, and started async-ing another part of the site. Again, I hit more dynamic user-controls, but this time the async call was in the load of the user-control rather than the page. I had exactly the same issue, except it was a drop down not persisting selections, rather than a panel visibility not persisting. I figured out I needed to call the asyn method in the following way

 Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

    Dim LoadTask As New PageAsyncTask(AddressOf OnBegin, AddressOf OnEnd, AddressOf OnTimeout, "AsyncTask1", True)
            Dim LoadTask As New PageAsyncTask(AddressOf OnBegin, AddressOf OnEnd, AddressOf OnTimeout, "AsyncTask1", True)

    Page.RegisterAsyncTask(LoadTask)
    Page.ExecuteRegisteredAsyncTasks()

    PrintGraph()

    End If 
  End Sub

手动传递true强制执行并行处理,并调用ExecuteRegisteredAsyncTasks修复了cuser-ontrols和整个页面的问题.现在,它可以完美地异步工作.我要做的唯一一件事是,在项目中添加了以下内容,从而影响了项目中的其他异步调用:

It was both manually passing true to force parallel processing, and calling ExecuteRegisteredAsyncTasks that fixed it for the cuser-ontrols and this page as a whole. It now works perfectly async. The only extra thing I did have to do, which effects other async calls in the project was add the following to the config:

    <add key="aspnet:UseTaskFriendlySynchronizationContext" value="false" />

唯一让我感到沮丧的是,我必须使用完全重载的方法(onLoad,OnEnd,OnTimeOut,State,Parallel)来调用所有PageAsyncTask,而不仅仅是传递main方法.我认为是由于添加密钥后必须手动处理超时,但我不确定.

The only bummer with this is, I have to call all PageAsyncTask using the fully overloaded method (onLoad,OnEnd,OnTimeOut,State,Parallel), rather than just passing the main method. I think due to having to handle the TimeOut manually after adding the key, but I am not sure.

Sooo ...然后我尝试利用这些知识来解决我的原始问题,但现在仍然没有!!

Sooo... I then tried to take this knowledge to help with my original issue, and it is still not having it!

所以我可以:

1)使用以下命令,异步加载数据,并在初始时加载页面正常,但是任何回发操作都会将用户控件恢复为原始状态.这也会对我遇到的另一个异步问题产生影响,这意味着所有未来的异步任务都需要按照第2项进行注册,因此这将重新破坏该工作页面.

1) Use the following, load the data async, and load the page fine initially, but any postback reverts user-controls back to original state. This would also have a knock on effect to the other async issue I had, which meant all future async tasks needed to be registered as per item 2, so this would re-break that now working page.

    Dim LoadTask As New PageAsyncTask(AddressOf Update)
    Page.RegisterAsyncTask(LoadTask)

2)使用以下命令,它不等待注册的异步方法完成(据我所知),因此,在加载网页时基本上不更新任何控件.根据评论,我接受我可能没有做的其他错误.

2) Use the following, which does not wait for the registered async method to complete (from what I can tell), so loads the webpage without essentially updating any controls. As per a comment, I accept there maybe something else wrong, that I have failed to do.

     Protected Sub Page_Load(ByVal sender As Object, ByVal e As 
     Dim LoadTask As New PageAsyncTask(AddressOf OnBegin, AddressOf OnEnd, AddressOf OnTimeout, "AsyncTask1", True)
    Page.RegisterAsyncTask(LoadTask)
    End Sub

如果我不按照MS docs使用IAsyncResult方法,而仅调用OnBegin方法,则可以在与项目1相同的程度上完成这项工作,但是仍然存在与1相同的问题.

I can make this work to the same extent as item 1, if I don't use the IAsyncResult approach as per MS docs, and just call the method for OnBegin, but this still has the same issue as 1.

     Protected Sub Page_Load(ByVal sender As Object, ByVal e As 
     Dim LoadTask As New PageAsyncTask(AddressOf Update, AddressOf OnEnd, AddressOf OnTimeout, "AsyncTask1", True)
    Page.RegisterAsyncTask(LoadTask)
    End Sub

请注意,在用户控件调用异步加载方法的其他页面情况下,我可以成功使用IAsyncResult方法.

it should be noted I can use the IAsyncResult approach successfully in the other page scenario where the user-control is calling the async load method.

    Private _dlgt As AsyncTaskDelegate
    Protected Delegate Sub AsyncTaskDelegate()

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

    Dim LoadTask As New PageAsyncTask(AddressOf OnBegin, AddressOf OnEnd, AddressOf OnTimeout, "AsyncTask1", True)

    Page.RegisterAsyncTask(LoadTask)
    Page.ExecuteRegisteredAsyncTasks()

    PrintGraph()

    End sub 


 Public Function OnBegin(ByVal sender As Object, ByVal e As EventArgs, ByVal cb As AsyncCallback, ByVal extraData As Object) As IAsyncResult

    _dlgt = New AsyncTaskDelegate(AddressOf ReLoadSelectors)
    Dim result As IAsyncResult = _dlgt.BeginInvoke(cb, extraData)

    Return result
End Function

`3)同步加载数据,一切都可以再次工作,包括保留其值的用户控件,但速度非常慢.

`3) Load the data synchronous, and everything just works again, including the user-controls persisting their values, but just dead slow.

我对这件事不屑一顾.可以对所有内容进行良好的同步,但不是异步的.使其能够在一个页面上工作,用户控件需要在该页面上执行异步加载调用,但不能使其在另一个页面上工作,而该页面必须在该页面上执行异步加载调用.一种类型的任务注册等待异步数据方法返回,但是使用IAsyncResult的完全重载版本则不会.

I am going out of my mind with this one. Works fine sync for everything, just not async. Manged to get it to work on one page, where the user-control needs to do the async load call, but cannot make it work on another page, where the page has to do the async load call. One type of task registration waits for the async data method to return, but the fully overloaded version using IAsyncResult does not.

请任何人发现我出了问题的地方,并将我从痛苦中解脱出来,我将非常感激.

Please if anyone can spot where I have gone wrong, and put me out of my misery, I would be so grateful.

推荐答案

是的,您需要将Page.Async设置为true才能使用RegisterAsyncTask.确保所有注册的任务在页面预渲染事件之前完成.

Yes, you need to set Page.Async to true in order to use RegisterAsyncTask. All the registered tasks are guaranteed to finish before page prerender event.

AsyncTaskDelegate的定义是什么?为什么不使用PageAsyncTask.ctor(Func handler)?像下面这样.

what's the definition of AsyncTaskDelegate? Why not use PageAsyncTask.ctor(Func handler) ? Something like below.

Dim LoadTask As New PageAsyncTask(AddressOf Update)
Page.RegisterAsyncTask(LoadTask)

这篇关于在异步方法上调用RegisterAsyncTask的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆