先说明一下我的功能要求(asp.net):要实现收邮件的功能,能让用户了解当前接收进度或情况。
  现在我的设计思路是这样的,进入接收页面后,创建一个接收邮件的线程。定义一个事件代理,在执行到某个步骤时执行代理,这个代理是异步调用的(在主线程执行,这样才能使用Response,Request)。现在有点不解的是,在这个事件函数执行时只要执行到Response.Write()或它的其它方法时就停止执行了,它就认为异步调用已经完成了。下面给出大致代码:
   //
   // 创建一个线程
   // 
   Thread m_receiveThread = new Thread(new ThreadStart(ReceiveThread));
   Session["Thread"] = m_receiveThread;
   m_receiveThread.Start();
   m_receiveThread.Priority = ThreadPriority.Lowest;//
//  线程函数体
//
  private void ReceiveThread()
  {
  //
  // 接收邮件类
  //
      ReceiveMailBus m_receiver = new ReceiveMailBus(Att_EmailAccounts,Att_CurrentEmailAccountId,m_resetEvent);
  //
  // 事件关联
  //
      m_receiver.OnReceive += new ReceiveEventHander(this.OnReceive);
     int m_intReceiveCount = m_receiver.Receive(Att_MessageId,Att_EmailList);
   }
  /// 连接
   public bool Connect()
   {
       if(OnReceive != null)
       {
//就是这边进行异步调用,为的就是让这个函数能在主线程中执行
IAsyncResult m_ar = OnReceive.BeginInvoke(this,new ReceiveEventArgs(STR_ONCONNECT,true,false),null,null);
         bool m_b = m_ar.IsCompleted;//调用完这里的值是true
if(m_b)
  OnReceive.EndInvoke(m_ar);
}
        try
        {
string m_strPOP3 = m_EmailSetupRow[EmailAccountData.STR_POP3_FIELD].ToString();
m_pop3.Connect(m_EmailSetupRow[EmailAccountData.STR_LOGINNAME_FIELD].ToString(),m_strPwd,m_strPOP3,m_intPop3Port);
}
catch(Exception exp)
{
     if(OnReceive != null)
     OnReceive(this,new ReceiveEventArgs(STR_CONNECT_ERR + ":" + exp.Message,false,true));
throw new CustomException(STR_CONNECT_ERR+ ":" + exp.Message,exp);
          }
if(OnReceive != null)
{
            IAsyncResult m_ar = OnReceive.BeginInvoke(this,new ReceiveEventArgs(STR_ONCONNECT,true,false),null,null);
}
     }
     private void OnReceive(object sender,ReceiveEventArgs e)
     {
        //
        //  孟子老大那借来的代码,假的进度显示
        //
Response.Write("<script>mydiv.innerText = '22222';</script>"); //事件执行到这句,函就算结束了,下面的语句都不执行了。但如果这前面有其它语句,不是Response物件的,都能执行,但是不管怎么样,一执行到Response这里就退出了。
Response.Write("<script language=javascript>;");
Response.Write("var dots = 0;var dotmax = 10;function ShowWait()");
Response.Write("{var output; output = '" + e.Att_strMessage + "';dots++;if(dots>=dotmax)dots=1;");
Response.Write("for(var x = 0;x < dots;x++){output += '·';}mydiv.innerText =  output;}");
Response.Write("function StartShowWait(){mydiv.style.visibility = 'visible'; ");
Response.Write("window.setInterval('ShowWait()',1000);}");
Response.Write("function HideWait(){mydiv.style.visibility = 'hidden';");
Response.Write("window.clearInterval();}");
Response.Write("StartShowWait();</script>");
Response.Flush();
      }为了能让你看清楚,特意排了一下。能理解我的意思吗?再说一遍我的目的,工作线程的进度在主线程体现出来。试过AutoResetEvent进行同步控制,但考虑到不能让主线程处于等待状态,(因为要等待工作线程的工作,这样就不接受客户的请求).

解决方案 »

  1.   

    IAsyncResult m_ar = OnReceive.BeginInvoke(this,new ReceiveEventArgs(STR_ONCONNECT,true,false),null,null);
             bool m_b = m_ar.IsCompleted;//调用完这里的值是true
    if(m_b)
      OnReceive.EndInvoke(m_ar);
    }
    由于是异步调用,所以bool m_b = m_ar.IsCompleted;这个语句会立刻执行,这句话应该放在异步事件里才对。
      

  2.   

    你说放在OnReceive()里?
    可是这个跟我的异步执行函数有什么关系呢,它只是判断异步函数是否已经执行结束了。可是如果在异步函数里没有执行Response的方法的话就能正常退出,如果有的话就执行到第一个Response的方法时函数就退出了,是Response这个物件的问题我想。