使用IAsyncResult和AsyncCallback调用多个WCF服务

时间:2011-11-30 09:41:48

标签: iasyncresult asynccallback

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

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&amp;永远不会设置MyLabelII文本,因为页面在5秒后加载

并释放线程。通过写入EventLog,可以正确调用End方法。 我怎么解决这个问题...... 像“一切都从头开始然后都等到一切都完成......” 我知道如果我的执行线程等待5秒钟,那么代码会根据需要执行..

我应该如何使用AsyncWaitHandle ...

1 个答案:

答案 0 :(得分:0)

嗯,这个问题的答案是&#34; System.Web.UI.PageAsyncTask&#34; class.It允许异步调用任务并等待

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

了解更多信息...将在Asp.Net 2.0&amp;仅限以上。

对于我们上面的问题...我正在使用&#34;我的算法&#34;作为同步和其他任务作为Async parallel。所以我的页面将需要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;
}
}

Works :)代码可以通用重构进行通用...

在计划这种设计时请小心......虽然......在内部这也必须使用来自线程池的线程

只有......我没有深挖..但必须是......所以如果任务碰巧花费的时间比计划的多,而且还有几个这样的任务

同时加薪,然后网络服务器可能会受到影响,用户可能会抽出时间......

我仍在进行这项工作,尽管存在上述缺陷,因为我的用户无论如何都会超时,如果25秒是55

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

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