0

我有一个网页 MyWebPage.aspx,它在加载时必须显示来自两个 web 服务的数据以及它自己的算法。

1) WebServiceI.SomeMethod() -> Takes 10 seconds aprx. to respond.
2) WebServiceII.SomeMethod() -> Takes 10 seconds aprx. to respond.
3) My Algorithm -> Takes 5 second aprx to respond.

现在,当我同步调用它时,加载需要 10+10+5 = 25 秒。

所以,有人建议我使用“异步调用方法”,即使用 IAsyncResult/AsyncCallback。现在将(应该)发生的是所有将同时调用并且页面将在最多 10 秒内加载。

所以我现在以“开始/结束”的方式称呼他们......

public partial class MyWebPage : System.Web.UI.Page
{
    WebServiceI WebServiceIObject = new WebServiceI();
    WebServiceII WebServiceIIObject = new WebServiceII();

protected void Page_Load(object sender, EventArgs e)
{
    //BeginSomeMethod(AsyncCallback callback, object asyncState)[<- Method Signature]
    WebServiceIObject.BeginSomeMethod(OnEndGetWebServiceISomeMethodResult, null);


    //BeginSomeMethod(AsyncCallback callback, object asyncState)[<- Method Signature]
    WebServiceIIObject.BeginSomeMethod(OnEndGetWebServiceIISomeMethodResult, null);


/* My Algorithm 5 seconds*/
DataSet DS = GetDataSetFromSomeWhere();
MyGataGrid.DataSource = DS.tables[0];
MyGataGrid.DataBind();
/* My Algorithm 5 seconds*/


//System.Threading.Thread.Sleep(6000);
}

//Will be called after 10 seconds
void OnEndGetWebServiceISomeMethodResult(IAsyncResult asyncResult)
{
string WebServiceISomeMethodResult = WebServiceIObject.EndSomeMethod(asyncResult);
MyLabelI.Text = WebServiceISomeMethodResult;
//EventLog MyLog = new EventLog("Application"); MyLog.Source = "MySourceI";
//MyLog.WriteEntry(DateTime.Now.ToString());
}

//Will be called after 10 seconds
void OnEndGetWebServiceIISomeMethodResult(IAsyncResult asyncResult)
{
string WebServiceIISomeMethodResult = WebServiceIIObject.EndSomeMethod(asyncResult);
MyLabelII.Text = WebServiceIISomeMethodResult;
//EventLog MyLog = new EventLog("Application"); MyLog.Source = "MySourceII";
//MyLog.WriteEntry(DateTime.Now.ToString());
}
}

现在上面示例的问题是 MyLabelI 和 MyLabelII 文本从未设置,因为页面在 5 秒后加载

并且线程被释放。通过写入 EventLog 来检查两个结束方法都被正确调用。我该如何解决这个问题......像“所有都立即开始,然后都等到所有完成......”我知道如果我的执行线程再等待 5 秒,那么代码将按要求执行..

我应该如何使用 AsyncWaitHandle...

4

1 回答 1

0

好吧,这个问题的答案是“System.Web.UI.PageAsyncTask”类。它允许异步调用任务并等待

在同一个线程上完成。也可以创建多个任务并使其并行运行。请阅读文档

如需更多信息...仅适用于 Asp.Net 2.0 及更高版本。

对于我们上面的问题......我将“我的算法”作为同步并将其他两个任务作为异步并行。所以我的页面将需要 10+5

= 15 秒加载。

public partial class MyWebPage : System.Web.UI.Page
{
WebServiceI WebServiceIObject = new WebServiceI();
WebServiceII WebServiceIIObject = new WebServiceII();

protected void Page_Load(object sender, EventArgs e)
{
PageAsyncTask PAT_I = new PageAsyncTask
(BeginGetWebServiceISomeMethodResult, OnEndGetWebServiceISomeMethodResult, null, null, true);
Page.RegisterAsyncTask(PAT_I);

PageAsyncTask PAT_II = new PageAsyncTask
(BeginGetWebServiceIISomeMethodResult, OnEndGetWebServiceIISomeMethodResult, null, null, true);
Page.RegisterAsyncTask(PAT_II);

Page.ExecuteRegisteredAsyncTasks();

/* My Algorithm 5 seconds*/
DataSet DS = GetDataSetFromSomeWhere();
MyGataGrid.DataSource = DS.tables[0];
MyGataGrid.DataBind();
/* My Algorithm 5 seconds*/
}

IAsyncResult BeginGetWebServiceISomeMethodResult
    (object Sender, EventArgs EventArgsObject, 
    AsyncCallback AsyncCallbackObject, object PassAnythingExtraIfRequired)
{
    return WebServiceIObject.BeginSomeMethod(AsyncCallbackObject, PassAnythingExtraIfRequired);
}

 IAsyncResult BeginGetWebServiceIISomeMethodResult
    (object Sender, EventArgs EventArgsObject, 
    AsyncCallback AsyncCallbackObject, object PassAnythingExtraIfRequired)
{
    return WebServiceIIObject.BeginSomeMethod(AsyncCallbackObject, PassAnythingExtraIfRequired);
}

void OnEndGetWebServiceISomeMethodResult(IAsyncResult asyncResult)
{
string WebServiceISomeMethodResult = WebServiceIObject.EndSomeMethod(asyncResult);
MyLabelI.Text = WebServiceISomeMethodResult;
}

void OnEndGetWebServiceIISomeMethodResult(IAsyncResult asyncResult)
{
string WebServiceIISomeMethodResult = WebServiceIIObject.EndSomeMethod(asyncResult);
MyLabelII.Text = WebServiceIISomeMethodResult;
}
}

作品 :) 代码可以通过常见的重构变得通用......

不过,在规划这种设计时请小心……在内部这也必须使用线程池中的线程

只是......我没有深入挖掘......但必须......所以如果任务发生的时间比计划的要多,并且如果有几个这样的任务

同时被提升,那么网络服务器可能会受到影响,用户可能会超时......

尽管存在上述缺陷,但我仍在继续前进,因为如果 25 秒变成 55 秒,我的用户无论如何都会超时

秒......最好有一些用户能够工作而不是没有工作的情况......

如果有更好的选择,请发帖。

于 2011-12-01T12:38:16.930 回答