在Asp.net中调用异步方法-使用信号量

有些库可能只提供了异步方法,而ASP.net确是同步的,这次就遇到一个问题:页面显示出来以后才会执行回调函数。而我需要的流程是:在回调函数中执行验证,然后才能呈现页面。Mutex,AutoResetEvent提供了通过信号量来协调线程执行步骤的方法。

XmppClientConnection是agsxmppJabber库中的类,调用Open会立即返回客户端(ie)呈现该页面,而不管是否成功,同时会在另一个线程会执行登陆,新建帐户的操作,成功后会触发回调事件,这样一来页面呈现后才会执行回调,不符合我们要的逻辑。我们把调用Open的线程叫做:Jabber线程,把执行登陆的线程叫做:Jabber线程的辅助线程。

我最初的想法是使用Moniter,代码:

private object objlock=new object();
     public void RegisterJab(string username, string password, string server)
     {
       _connection.Server = server;
       _connection.Username = username;
       _connection.Password = password;
       _connection.Port = 80;
       _connection.UseSSL = false;
       _connection.AutoResolveConnectServer = true;
       _connection.ConnectServer = null;
       _connection.SocketConnectionType = agsXMPP.net.SocketConnectionType.Direct;
       _connection.UseStartTLS = true;
       _connection.RegisterAccount = true;
       Moniter.Enter(objlock);
       _connection.Open();
       Moniter.Wait(objlock);
       _connection.Close();
     }
     private void XmppCon_OnRegistered(object sender)
     {
       IsSuccessfull = true;
       Moniter.Exit(objlock);
     }

在执行Moniter.Exit()时会抛出异常:SynchronizationLockException,因为Jabber辅助线程并不是锁的拥有者.发现Moniter很像临界区,并不适处理这种情况合。

后来,转到了Mutex,Mutex: 是同步基元,它只向一个线程授予对共享资源的独占访问权。如果一个线程获取了互斥体,则要获取该互斥体的第二个线程将被挂起,直到第一个线程释放该互斥体。

Mutex很合适这个功能的实现,可是还有没有更简便的方法呢?那就是AutoResetEvent:允许线程通过发信号互相通信。通常,此通信涉及线程需要独占访问的资源。最重要的是他提供了线程间通讯的方法,这样可以更灵活的控制线程的调用步骤,我们用到的就是信号量。

代码:

namespace LoginBase
{
   public class Register
   {
     XmppClientConnection _connection;
     static AutoResetEvent myResetEvent;
     public bool IsUsed;
     public Register()
     {
       _connection = new XmppClientConnection();
       _connection.SocketConnectionType = agsXMPP.net.SocketConnectionType.Direct;
       _connection.OnLogin += new ObjectHandler(XmppCon_OnLogin);
       _connection.OnRegisterError += new OnXmppErrorHandler(XmppCon_OnRegErr);
       _connection.OnRegistered += new ObjectHandler(XmppCon_OnRegistered);
     }
     public bool IsSuccessfull = false;
     public void RegisterJab(string username, string password, string server)
     {
       _connection.Server = server;
       _connection.Username = username;
       _connection.Password = password;
       _connection.Port = 80;
       _connection.UseSSL = false;
       _connection.AutoResolveConnectServer = true;
       _connection.ConnectServer = null;
       _connection.SocketConnectionType = agsXMPP.net.SocketConnectionType.Direct;
       _connection.UseStartTLS = true;
       _connection.RegisterAccount = true;
       myResetEvent = new AutoResetEvent(false);
       _connection.Open();
       myResetEvent.WaitOne(20 * 1000, true);
       _connection.Close();
     }
     private void XmppCon_OnRegistered(object sender)
     {
       IsSuccessfull = true;
       myResetEvent.Set();
     }
     private void XmppCon_OnLogin(object sender)
     {
       IsSuccessfull = true;
       myResetEvent.Set();
     }
     private void XmppCon_OnRegErr(object sender, Element e)
     {
       //errCode如果是409则已经存在用户
       IsSuccessfull = false;
       Element xn = e.SelectSingleElement("error");
       if (xn.Attribute("code") == "409")
         IsUsed = true;
       myResetEvent.Set();
     }
   }
}

先设置为非终止状态,然后进入Jabber线程,阻塞Asp线程,并且等待,超时时间为20秒。如果触发了回调事件,则设置状态为终止,asp线程继续执行。

成功完成同步,这样一来,必须等到Jabber辅助线程执行完,Asp线程才会继续下去。

时间: 2024-10-27 12:08:02

在Asp.net中调用异步方法-使用信号量的相关文章

在ASP文件中调用DLL

在ASP文件中调用DLL 动态联接库(DLL)是加快应用程序关键部分的执行速度的重要方法,但有一点恐怕大部分人都不知道,那就是在ASP文件也能通过调用DLL来加快服务器的执行速度,下面我简单的介绍一下在ASP文件调用DLL的步骤. 首先,必须得有DLL文件,本例是通过VB5.0创建ActiveX DLL文件,这个文件模拟了一个掷色子的过程. 在VB5.0的环境下,新建一个工程,并双击新建工程窗口中ActiveX DLL图标,VB将自动为项目添加一个类模块,并将该项目类型设置为ActiveX DL

在asp/asp.net中调用java写的类

asp.net|asp.net 在开发过程中偶尔会遇到要在ASP/ASP.Net中调用JAVA写的类,以实现之前已经用JAVA实现的功能,下面就以一个简单示例说明详细的使用方法: 1.创建java文件:使用任何你喜欢的编辑器编辑以下内容:public class hello{ public String helloWorld(String s) { if(s == null) return ""; else return s; }}将此文件保存为hello.java 2.编译java文

asp.net中调用存储过程的方法_实用技巧

本文实例讲述了asp.net中调用存储过程的方法.分享给大家供大家参考,具体如下: 一.建立并调用一个不带参数的存储过程如下: CREATE PROCEDURE 全部学生<dbo.selectUsers> AS SELECT * FROM 学生 GO EXEC 全部学生 建立并调用一个带参数的存储过程如下: CREATE PROCEDURE 学生查询1 @SNAME VARCHAR(8),@SDEPT VARCHAR(20) AS SELECT * FROM 学生 WHERE 姓名=@SNAM

asp.net 中调用cmd并查询IP信息

asp.net 中调用cmd并查询ip信息 private static string cmdping(string cmd)   {       process p = new process();       p.startinfo.filename = "cmd.exe";       p.startinfo.useshellexecute = false;       p.startinfo.redirectstandardinput = true;       p.start

ASP程序中调用函数Now()异常的问题

新上的一台服务器出现了一个现象:ASP程序中,调用函数Now(),显示的时间总是形如"2009-07-12 上午 08:12:56 "这样的,总显示"上午"和"下午",解决过程及最终解决方法如下: 这么显示,一般都是因为服务器就是如此设置的,先查看时间格式:直接双击任务栏中时间,在弹出的"时间和日期"中果然显示了上午下午这样的字样,那就进入下一步设置: 打开控制面板,选择"区域和语言选项",在"区

在ASP.NET中调用存储过程方法新解

asp.net|存储过程 在使用.NET的过程中,数据库访问是一个很重要的部分,特别是在B/S系统的构建过程中,数据库操作几乎成为了一个必不可少的操作.调用存储过程实现数据库操作使很多程序员使用的方法,而且大多数的程序员都是能使用存储过程就使用存储过程,很少直接使用SQL语句,所以存储过程是很有用而且很重要的. 存储过程简介 简单的说,存储过程是由一些SQL语句和控制语句组成的被封装起来的过程,它驻留在数据库中,可以被客户应用程序调用,也可以从另一个过程或触发器调用.它的参数可以被传递和返回.与

解析在ASP.NET中调用存储过程的方法

在使用.NET的过程中,数据库访问是一个很重要的部分,特别是在B/S系统的构建过程中,数据库操作几乎成为了一个必不可少的操作.调用存储过程实现数据库操作使很多程序员使用的方法,而且大多数的程序员都是能使用存储过程就使用存储过程,很少直接使用SQL语句,所以存储过程是很有用而且很重要的. 存储过程简介 简单的说,存储过程是由一些SQL语句和控制语句组成的被封装起来的过程,它驻留在数据库中,可以被客户应用程序调用,也可以从另一个过程或触发器调用.它的参数可以被传递和返回.与应用程序中的函数过程类似,

在ASP.NET中调用存储过程方法新解_自学过程

在使用.NET的过程中,数据库访问是一个很重要的部分,特别是在B/S系统的构建过程中,数据库操作几乎成为了一个必不可少的操作.调用存储过程实现数据库操作使很多程序员使用的方法,而且大多数的程序员都是能使用存储过程就使用存储过程,很少直接使用SQL语句,所以存储过程是很有用而且很重要的. 存储过程简介 简单的说,存储过程是由一些SQL语句和控制语句组成的被封装起来的过程,它驻留在数据库中,可以被客户应用程序调用,也可以从另一个过程或触发器调用.它的参数可以被传递和返回.与应用程序中的函数过程类似,

asp.net中调用Office来制作3D统计图

asp.net|统计 1.首先下载owc11 COM组件 http://www.microsoft.com/downloads/details.aspx?FamilyID=7287252c-402e-4f72-97a5-e0fd290d4b76&displaylang=en 2.注册owc11 在工程中添加 C:\Program Files\Common Files\Microsoft Shared\Web Components\11  文件下的owc11.dll引用 3.在工程中添加 usin