做了个windows服务,在服务中利用了两个timer控件,一个负责接收数据,一个负责发送数据,声明了一个数据库连接对象,在运行时发现经常提示数据库连接已关闭的错误,不知道是什么原因呢。后来我改成了两个数据库连接对象,一个由接收服务调用一个由发送服务调用,这样就没有上述错误发生了。不过还是不太明白是什么原因呢,请帮忙了。

解决方案 »

  1.   

    你是不是在接收和发送的时候都调用了数据库关闭啊(*.close)或者是释放了数据连接!
      

  2.   

    发送和接收只是在一个服务中的两个方法而已呀,实际上还是一个服务的
    但是我看了System.Timers.Timer是多线程的,是不是一个数据库连接不能在多线程中使用啊
      

  3.   

    因为Connection对象不是线程安全的。
      

  4.   

    把代码拿出来看看 。回楼上的 应该不是那问题。
    可能是dataset
      

  5.   

    private void ReceiveTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
    {
        if (Interlocked.Exchange(ref _receiveRunning,1)==0)
            ReceiveNote();
    }
    private void ReceiveNote()
    {
        try
        {
            int noteid = Core.NoteCore.Receive(_cnnReceive, null);
            NoteEntity n = Core.NoteCore.GetEntity(noteid, _cnnReceive);
            //自动回复短信
            Core.NoteCore.Revert(n, _cnnReceive, _revertcontent);
            WriteLog("接收短信成功:短信id=" + noteid.ToString());
        }
        catch (Exception ex)
        {
            //WriteLog("接收短信失败:" + ex.Message);
        }
        finally
        {
            Interlocked.Exchange(ref _receiveRunning, 0);
        }
    }
    private void SendTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
    {
        if (_vipbirthday && Interlocked.Exchange(ref _sendVipBirthRunning,1)==0)
            SendVipBirthday();
        if (_empbirthday && Interlocked.Exchange(ref _sendEmpBirthRunning,1)==0)
            SendEmpBirthday();
        if (Interlocked.Exchange(ref _sendatonceruning,1)==0)
            SendAtOnce();
        if (Interlocked.Exchange(ref _sendtaskruning,1)==0)
            SendTask();
    }
    private void SendVipBirthday()
    {
        try
        {
            if ((int)Database.ExecScalar("select count(*) from SendTaskLog where ftaskid=-1 and convert(varchar(10),fStartTime,120)"
                + "=convert(varchar(10),getdate(),120)", _cnnSend) == 0)
            {
                DataSet ds = Database.GetDataSet("select fmobile from viparchive where month(dateadd(day,"
                    + "-" + _vipbirthdayahead.ToString() + ",fbirthday))=month(getdate()) and day(dateadd(day,"
                    + "-" + _vipbirthdayahead.ToString() + ",fbirthday))=day(getdate())", _cnnSend, "vip");
                string t = DateTime.Now.ToString();
                //写入日志
                Database.ExecCommand("insert into SendTaskLog(ftaskid,fstarttime) values(-1,'" + t + "')", _cnnSend);
                foreach (DataRow row in ds.Tables["vip"].Rows)
                {
                    int smsid;
                    Note.Send(row["fmobile"].ToString(), _vipbirthdaynote, out smsid);
                    Core.NoteCore.Send(new NoteEntity(row["fmobile"].ToString(), _vipbirthdaynote, smsid, DateTime.Now.ToString()), _cnnSend, null);
                }
                //写完成标志
                Database.ExecCommand("update SendTaskLog set fEndTime='" + DateTime.Now.ToString() + "',fSuccessed=1"
                    + " where fTaskID=-1 and fStartTime='" + t + "'", _cnnSend);
            }
        }
        catch (Exception ex)
        {
            WriteLog("发送会员生日短信失败:" + ex.Message);
        }
        finally
        {
            Interlocked.Exchange(ref _sendVipBirthRunning, 0);
        }
    }
    其他的几个发送的方法跟这个类似的
      

  6.   

    我的猜测:timer是异步的,.net有自动回收机制,有可能在一个线程完成后自动关闭.
      

  7.   

    看来确实是出在connection与多线程上了,多谢各位了