【发布时间】:2009-05-11 22:51:08
【问题描述】:
我在类库中有以下代码。我等待回电到我的主应用程序。我正在进行 DownloadStringAsync 调用,因此在完成后我必须等待几秒钟才能获得回调。我有 3 个这样的调用要等待,所以在我的主应用程序中,我使用 AutoResetEvent 来等待它们全部完成。所以我会阻塞,直到它们在回调函数中被设置。
但是,在测试回调后不会被调用。我在想,当代码被 AutoResetEvent 阻止时,它会阻止 DownloadStringAsync。当我注释掉这段代码时,一切正常。
所以我想只要我打电话给:objNoGateway.NoGatewayStatus(sipUsername, statusDisplay1.PhoneNumber); 当代码到达这里时:handle.WaitOne(); 它会阻塞类库中的代码。
非常感谢您的建议。
在我的类库代码示例中。
// Event handler that makes a call back in my main application
// Event handler and method that handles the event
public EventHandler<NoGatewayEventArgs> NoGatewayCompletedEvent;
// The method that raises the event.
private void OnNoGatewayCompleted(object sender, NoGatewayEventArgs e)
{
if (NoGatewayCompletedEvent != null)
{
NoGatewayCompletedEvent(this, e);
}
}
// Start the Async call to find if NoGateway is true or false
public void NoGatewayStatus(string sipUsername, string phoneNumber)
{
string strURL = string.Format("http://xxxxxxxxxxxxxxx={0}&CalledNumber={1}", sipUsername, phoneNumber);
if (!wc.IsBusy)
{
try
{
string errorMsg = string.Empty;
wc.DownloadStringAsync(new Uri(strURL));
}
catch (WebException ex)
{
Console.WriteLine("IsNoGateway: " + ex.Message);
}
catch (Exception ex)
{
Console.WriteLine("IsNoGateway: " + ex.Message);
}
}
else
{
Console.WriteLine("WebClient: IsNoGateWay(): Busy please try again");
}
}
void wc_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
if (e.Error == null)
{
if (e.Result == "No gateway")
{
OnNoGatewayCompleted(this, new NoGatewayEventArgs(validateResponse_e.VALIDATION_FAILED));
Console.WriteLine("NoGatway() DownloadedCompleted: " + e.Result);
}
else
{
OnNoGatewayCompleted(this, new NoGatewayEventArgs(validateResponse_e.OK));
Console.WriteLine("NoGateway() DownloadCompleted: " + e.Result);
}
}
else
{
this.OnNoGatewayCompleted(this, new NoGatewayEventArgs(validateResponse_e.SERVER_FAILED));
Console.WriteLine("No Gateway: DownloadCompleted() Error: " + e.Error.Message);
}
}
在我的主应用程序中,我注册了这个回调。并等待结果。然后设置 AutoResetEvent。
ManualResetEvent[] waitValidateCallResponse = new ManualResetEvent[]
{ new ManualResetEvent(false), new ManualResetEvent(false), new ManualResetEvent(false) };
// Event handler for NoGateway event
private void OnNoGatewayCompleted(object sender, NoGatewayEventArgs e)
{
Console.WriteLine("OnNoGatewayComleted: " + e.noGateway);
waitValidateCallResponse[0].Set();
}
我打电话和阻止的部分。
NoGateway objNoGateway = new NoGateway()
objNoGateway.NoGatewayCompletedEvent += new EventHandler<NoGatewayEventArgs>(this.OnNoGatewayCompleted);
objNoGateway.NoGatewayStatus(sipUsername, statusDisplay1.PhoneNumber);
// Block here - Wait for all reponses to finish before moving on
waitEvent.WaitOne(5000, true);
Console.WriteLine("All thread finished");
======================== 编辑并添加其他 2 个回调,以免混淆我只有一个 ==== 的问题===================
private void OnCalledNumberBlockedCompleted(object sender, CalledNumberBlockedEventArgs e)
{
Console.WriteLine("OnCalledNumberBlockedCompleted: " + e.CalledNumberBlocked);
waitValidateCallResponse[1].Set();
}
private void OnValidTelephoneNumberCompleted(object sender, ValidTelephoneNumberEventArgs e)
{
Console.WriteLine("OnValidTelephoneNumberCompleted: " + e.validTelephoneNumber);
waitValidateCallResponse[2].Set();
}
【问题讨论】:
-
根据您的代码,您应该在控制台上阅读“events.WaitOne():” + handle.ToString() 一次,然后再挂起。你没有在你的帖子中谈论它,但这是一个有价值的线索。那么,发生了吗?
-
这条线永远不会到达:Console.WriteLine("events.WaitOne(): " + handle.ToString());
-
如果我必须调试它,我会在调试器中逐步完成。你能告诉我们哪些代码行执行,哪些不执行吗?回调是否正在执行?是否执行了 wc_DownloadStringCompleted 方法?在您的代码中,您没有显示调用 OnValidTelephoneNumberCompleted 和 OnCalledNumberBlockedCompleted 方法的位置。另外,这让我很恼火: public EventHandler
NoGatewayCompletedEvent;还有更远的...... NoGatewayCompletedEvent(this, e);好吧,这不应该编译,你没有写“事件”关键字。但这可能无关紧要。 -
我已经踩过很多次了。但是,我可以确认没有调用回调。一旦调用 waitOne() ,它就会冻结。回调应该需要更长的时间才能被调用,因为它必须从 Web 服务器接收消息。但是那个时候 waitOne 已经阻塞了。我想这可能很简单。但是,阅读别人的代码已经比较困难了。
-
如果你已将 WaitOne 更改为 WaitAll,则无需循环
标签: c# multithreading