Cha*_*had 9 timeout begininvoke
在网页上,我正在呼叫第三方,它不允许我以编程方式设置超时.我调用BeginInvoke并使用AsyncWaitHandle.WaitOne等待指定的时间.
如果呼叫超时,我继续前进,忘记我开始的线程呼叫.我的问题是,在超时情况下,我是否还要以某种方式调用EndInvoke?这个MSDN页面上的"注意"注释让我想知道我是否应该:http://msdn.microsoft.com/en-us/library/2e08f6yc(VS.71).aspx
如果您认为我应该,那么接下来的问题是,如果我的网页已经完成处理并在第三方回来之前返回到客户端,那么回调方法是否会在那里听取运行代码?一旦我的请求/响应完成,服务器是否停止寻找活动?
这是我正在使用的代码:
public class RemotePaymentProcessor
{
private delegate string SendProcessPaymentDelegate(string creditCardNumber);
private string SendProcessPayment(string creditCardNumber)
{
string response = string.Empty;
// call web service
SlowResponseService.SlowResponseService srs = new WebServiceTimeout.SlowResponseService.SlowResponseService();
response = srs.GetSlowResponse(creditCardNumber);
return response;
}
public string ProcessPayment(string creditCardNumber, int timeoutMilliseconds)
{
string response = string.Empty;
SendProcessPaymentDelegate sppd = new SendProcessPaymentDelegate(SendProcessPayment);
IAsyncResult ar = sppd.BeginInvoke(creditCardNumber, null, new object());
if (!ar.AsyncWaitHandle.WaitOne(timeoutMilliseconds, false))
{
// Async call did not return before timeout
response = "TIMEOUT";
}
else
{
// Async call has returned - get response
response = sppd.EndInvoke(ar);
}
return response;
}
}
Run Code Online (Sandbox Code Playgroud)
好吧,我不能忽视我到处看到的建议,如果我不确保调用 EndInvoke,我可能会泄漏一些资源,所以我不得不尝试在晚上睡觉,而不用担心我正在接近悬崖。
我找到的解决方案使用了异步回调函数。如果调用及时返回,我会在那里调用 EndInvoke。如果没有,我继续单击按钮,并让异步回调函数使用 EndInvoke 清理混乱。
为了回答我自己关于网络应用程序的问题以及“在我超时并继续前进后,是否有人会在那里听”,我发现他们会 - 即使我超时并继续前进,如果我观看了稍后的输出,那么异步即使我已经将输出返回给客户端,调用也会返回并运行回调函数。
我使用了一些我在以下位置找到的内容:http://www.eggheadcafe.com/tutorials/aspnet/847c94bf-4b8d-4a66-9ae5-5b61f049019f/basics-make-any-method-c.aspx
...以及与我在其他地方找到的回调内容相结合。这是我下面所做的一个小示例函数。它结合了我在感谢大家的意见中找到的一些内容!:
public class RemotePaymentProcessor
{
string currentResponse = string.Empty;
private delegate string SendProcessPaymentDelegate(string creditCardNumber);
private string SendProcessPayment(string creditCardNumber)
{
SlowResponseService.SlowResponseService srs = new WebServiceTimeout.SlowResponseService.SlowResponseService();
string response = srs.GetSlowResponse(creditCardNumber);
return response;
}
public string ProcessPayment(string creditCardNumber, int timeoutMilliseconds)
{
string response = string.Empty;
SendProcessPaymentDelegate sppd = new SendProcessPaymentDelegate(SendProcessPayment);
IAsyncResult ar = sppd.BeginInvoke(creditCardNumber, new AsyncCallback(TransactionReturned), sppd);
if (!ar.AsyncWaitHandle.WaitOne(timeoutMilliseconds, false))
{
// Async call did not return before timeout
response = "TIMEOUT";
}
else
{
// Async call has returned - get response
response = sppd.EndInvoke(ar);
}
currentResponse = response; // Set class variable
return response;
}
private void TransactionReturned(IAsyncResult ar)
{
string response = string.Empty;
// Get delegate back out of Async object
SendProcessPaymentDelegate sppd = (SendProcessPaymentDelegate)ar.AsyncState;
// Check outer class response status to see if call has already timed out
if(currentResponse.ToUpper().Equals("TIMEOUT"))
{
// EndInvoke has not yet been called so call it here, but do nothing with result
response = sppd.EndInvoke(ar);
}
else
{
// Transaction must have returned on time and EndInvoke has already been called. Do nothing.
}
}
}
Run Code Online (Sandbox Code Playgroud)