C# 线程和使用 AutoResetEvent

标签 c# multithreading

我在类库中有以下代码。然后我等待回拨到我的主应用程序中。我正在进行 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();
    }

最佳答案

是否简单到:您总是在索引 0 上调用 Set?

private void OnNoGatewayCompleted(object sender, NoGatewayEventArgs e)
{
    Console.WriteLine("OnNoGatewayComleted: " + e.noGateway);
    waitValidateCallResponse[0].Set();
}

关于C# 线程和使用 AutoResetEvent,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/847423/

相关文章:

c++ - OpenCV GPU Farneback 光流在多线程中运行不佳

java - 线程本地删除?

java - 更新 Java 线程池中的 UI

c# - 服务器在 CPU 负载过重或线程池繁忙时出现 WCF 可靠 session 故障

C# 和 Android/Java - 跨语言二进制流编写器/读取器? (对于原语和 UTF-8 字符串)

c# - 异步 Controller 通过 jQuery 阻止 ASP.NET MVC 中的请求

Java多线程系统

Java 多线程 : Behaviour when Reference count of thread object becomes zero

c# - 无法使用 jsonconverter 更新现有的 json 列表

c# - 如何使用 OpenXml 将大纲表格边框应用于单元格范围?