使用IAsyncResult和AsyncCallback调用多个WCF服务 [英] Calling multiple WCF service using IAsyncResult and AsyncCallback

查看:100
本文介绍了使用IAsyncResult和AsyncCallback调用多个WCF服务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

1)WebServiceI.SomeMethod()->大约需要10秒.回应.
2)WebServiceII.SomeMethod()->大约需要10秒.回应.
3)我的算法->需要5秒的时间才能响应.
现在,当我同步调用此代码时,将需要10 + 10 + 5 = 25秒才能加载.

因此,我被建议使用异步调用方法",即使用IAsyncResult/AsyncCallback.现在将(应该)发生的是所有这些都将被同时调用,并且页面将在最多10秒内加载.

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

公共局部类MyWebPage:System.Web.UI.Page
{
WebServiceI WebServiceIObject =新的WebServiceI();
WebServiceII WebServiceIIObject =新的WebServiceII();

受保护的void Page_Load(对象发送者,EventArgs e)
{
//BeginSomeMethod(AsyncCallback回调,对象asyncState)[<-方法签名]
WebServiceIObject.BeginSomeMethod(OnEndGetWebServiceISomeMethodResult,null);


//BeginSomeMethod(AsyncCallback回调,对象asyncState)[<-方法签名]
WebServiceIIObject.BeginSomeMethod(OnEndGetWebServiceIISomeMethodResult,null);


/*我的算法5秒*/
DataSet DS = GetDataSetFromSomeWhere();
MyGataGrid.DataSource = DS.tables [0];
MyGataGrid.DataBind();
/*我的算法5秒*/


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

//10秒后将被调用
void OnEndGetWebServiceISomeMethodResult(IAsyncResult asyncResult)
{
字符串WebServiceISomeMethodResult = WebServiceIObject.EndSomeMethod(asyncResult);
MyLabelI.Text = WebServiceISomeMethodResult;
//EventLog MyLog = new EventLog("Application"); MyLog.Source ="MySourceI";
//MyLog.WriteEntry(DateTime.Now.ToString());
}

//10秒后将被调用
void OnEndGetWebServiceIISomeMethodResult(IAsyncResult asyncResult)
{
字符串WebServiceIISomeMethodResult = WebServiceIIObject.EndSomeMethod(asyncResult);
MyLabelII.Text = WebServiceIISomeMethodResult;
//EventLog MyLog = new EventLog("Application"); MyLog.Source ="MySourceII";
//MyLog.WriteEntry(DateTime.Now.ToString());
}
}
现在,上述示例的问题是MyLabelI&永远不会设置MyLabelII Text,因为页面会在5秒钟后加载

并且通过释放两个方法都可以正确地调用End方法,方法是通过写入EventLog进行检查.我该如何解决这个问题……类似全部立即开始,然后全部等到全部完成..."的意思是,如果我的执行线程等待了5秒以上,则代码将按要求执行..

我应该如何使用AsyncWaitHandle ...

还是从服务器端编码根本无法实现?

I have one web page MyWebPage.aspx which while loading has to show data from two webservices along with it''s own algorithm.

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.
Now,when I call this synchronously,this will take 10+10+5 = 25 seconds to load.

So,I was suggested "Asynchronous Calling Method",i.e. using IAsyncResult/AsyncCallback. Now what will(should) happen is that all will be called simultaneously and the page will load in max 10 seconds.

So I call them now in the "Begin/End" way...

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());
}
}
Now the issue with the above example is that MyLabelI & MyLabelII Text are never set because the page loads after 5 seconds

and thread is released.Both End Methods are called correctly as checked by writing to EventLog. How can I resolve this... something like "All start at once and then all wait till all are complete..." I understand that if my executing thread waits for 5 seconds more then the code executes as required..

How should I use AsyncWaitHandle...

Or is it simply not possible from server side coding??

推荐答案

好,此问题的答案是"System.Web.UI.PageAsyncTask"类.它允许异步调用任务并等待在同一线程上完成.还可以创建多个任务并使它们并行运行.请仔细阅读文档以获取更多信息...将在Asp.Net 2.0和更高版本中工作.仅在上方.
对于上述问题...我将我的算法"设置为同步,将其他两个任务设置为异步并行".因此,我的页面将需要10 + 5 = 15秒的加载时间.

公共局部类MyWebPage:System.Web.UI.Page
{
WebServiceI WebServiceIObject =新的WebServiceI();
WebServiceII WebServiceIIObject =新的WebServiceII();

受保护的void Page_Load(对象发送者,EventArgs e)
{
PageAsyncTask PAT_I =新的PageAsyncTask
(BeginGetWebServiceISomeMethodResult,OnEndGetWebServiceISomeMethodResult,null,null,true);
Page.RegisterAsyncTask(PAT_I);
PageAsyncTask PAT_II =新的PageAsyncTask
(BeginGetWebServiceIISomeMethodResult,OnEndGetWebServiceIISomeMethodResult,null,null,true);
Page.RegisterAsyncTask(PAT_II);
Page.ExecuteRegisteredAsyncTasks();

/*我的算法5秒*/
DataSet DS = GetDataSetFromSomeWhere();
MyGataGrid.DataSource = DS.tables [0];
MyGataGrid.DataBind();
/*我的算法5秒*/
}
IAsyncResult BeginGetWebServiceISomeMethodResult
(对象发件人,EventArgs,EventArgsObject,
AsyncCallback AsyncCallbackObject,对象PassAnythingExtraIfRequired)
{
返回WebServiceIObject.BeginSomeMethod(AsyncCallbackObject,PassAnythingExtraIfRequired);
}

IAsyncResult BeginGetWebServiceIISomeMethodResult
(对象发件人,EventArgs,EventArgsObject,
AsyncCallback AsyncCallbackObject,对象PassAnythingExtraIfRequired)
{
返回WebServiceIIObject.BeginSomeMethod(AsyncCallbackObject,PassAnythingExtraIfRequired);
}

void OnEndGetWebServiceISomeMethodResult(IAsyncResult asyncResult)
{
字符串WebServiceISomeMethodResult = WebServiceIObject.EndSomeMethod(asyncResult);
MyLabelI.Text = WebServiceISomeMethodResult;
}
void OnEndGetWebServiceIISomeMethodResult(IAsyncResult asyncResult)
{
字符串WebServiceIISomeMethodResult = WebServiceIIObject.EndSomeMethod(asyncResult);
MyLabelII.Text = WebServiceIISomeMethodResult;
}
}
Works :)可以通过通用重构使代码通用...
不过,在规划此类设计时请小心...内部也必须仅使用线程池中的线程...我没有深入研究..但一定是..所以,如果任务恰好比计划花费了更多时间如果同时提出几个此类任务,则Web服务器可能会遭受损失,用户可能会超时...
尽管存在上述缺陷,但我仍会继续前进,因为如果25秒变成55秒,我的用户无论如何都会超时...更好的情况是某些用户能够工作而不是没有工作..
如果有更好的选择,请发表.
Well,The answer to this problem is "System.Web.UI.PageAsyncTask" class.It allows Asynchronous calls to tasks and waits for completion on the same thread.Also multiple tasks can be created and made to run parallel.Please go through the documentation for further information...Will work in Asp.Net 2.0 & Above Only.
For our problem above...I am putting "My Algorithm" as sync and both other tasks as Async parallel.So my page will take 10+5 = 15 seconds to load.

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 :) The code can be made generic with common refactoring...
Please be careful while planning for this kind of design though...Internally this must also be using threads from threadpool only...I have not dug in deep..but must be..So if the tasks happen to take moretime than planned and if several such tasks get raised at the same time,then web server could suffer and users could get time out...
I am still carrying this forward inspite of above flaw as my users will time out anyway if 25 seconds turns out to be 55 seconds...Better to have a situation where some users are able to work rather than none..
If there is some better alternative,please post.


这篇关于使用IAsyncResult和AsyncCallback调用多个WCF服务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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