2011-11-30 2 views
0

У меня есть одна веб-страница MyWebPage.aspx, которая при загрузке должна отображать данные из двух веб-сервисов вместе с собственным алгоритмом.Вызов нескольких служб WCF с использованием IAsyncResult и AsyncCallback

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 секунд.

Так я называю их теперь в «Begin/End» пути ...

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 ...

ответ

0

Ну, ответ на этот вопрос является «System.Web.UI.PageAsyncTask» class.It позволяет Асинхронные вызовы задач и ждет

завершения на тот же thread.Also несколько задач могут быть созданы и сделаны для запуска parallel.Please пройти документацию

для получения дополнительной информации ... Будет работать в Asp.Net 2.0 & Только выше.

Для нашей проблемы выше ... Я кладу «Мой алгоритм», как синхронизация и оба других задач, как асинхронный parallel.So моей страницы будет принимать 10 +-

= 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; 
} 
} 

работы :) Код может быть общим с общим рефакторинга ...

Пожалуйста, будьте осторожны при планировании такого рода дизайн, хотя ... Внутренне это также необходимо использовать темы от ThreadPool

только

... Я не копал в deep..but должны be..So если задачи произойдет принять moretime, чем планировалось, и если несколько таких задач

получить рейз в то же время, то веб-сервер может страдают, и пользователи могут получить тайм-аут ...

Я до сих пор несу этот вперед несмотр на выше изъян, как мои пользователи таймаут в любом случае, если 25 секунд оказываются 55

секунд ... Лучше иметь ситуацию, когда некоторые пользователи смогут работать, а чем нет.

Если есть какая-то лучшая альтернатива, отправьте сообщение.