登录界面在无法连接服务器时,界面会假死,如何解决?

解决方案 »

  1.   

    连接参数设一下timeout啊,默认是0的是一直连,可以设成5或10什么的就行了。
      

  2.   

    应该可以直接用trycatch抛出一个登陆异常出来的吧
      

  3.   

    设置一下应用连接池的connectiontimeout
    举个例子:connectiontimeout=5
    Data Source=localhost;Initial Catalog=DataClient;User ID=aaa;Password=aaa;connectiontimeout=5
      

  4.   

     good! study! 
      
      能否提供点源码?
      

  5.   


    WinForm程序,登录成功后需要show出主界面,怎么处理的?
      

  6.   

    Login login = new Login();
                if (login.ShowDialog() == DialogResult.OK)
                {
                    Application.Run(new MainWindow());
                }
      

  7.   

    namespace WindowsFormsApplication1
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }        public event EventHandler timeOutEvent;
            private System.Windows.Forms.Timer timer = null;
            private string user = null;
            private string pwd = null;
            Thread loginThread = null;
            private bool loginSucceed = false;        //登陆按钮
            private void button1_Click(object sender, EventArgs e)
            {
                this.user = textBox1.Text;
                this.pwd = textBox2.Text;
                loginThread = new Thread(new ThreadStart(CheckLogin));
                loginThread.IsBackground = true;
                loginThread.Start();
                timer.Start();
            }        private void Form1_Load(object sender, EventArgs e)
            {
                this.timeOutEvent += new EventHandler(LoginResult);
                timer = new System.Windows.Forms.Timer();
                timer.Interval = 10000;//10秒
                timer.Tick += new EventHandler(TimeOutEvent);
            }        private void LoginResult(object sender, EventArgs e)
            {
                this.label1.Text = loginSucceed ? "登陆成功" : "登陆失败";
            }        private void TimeOutEvent(object sender, EventArgs e)
            {
                timer.Stop();
                if (loginThread.IsAlive)
                {
                    loginThread.Abort();
                }            this.loginSucceed = false;
                FireEvent();
            }        /// <summary>
            /// 引发登陆操作完成的事件
            /// </summary>
            private void FireEvent()
            {
                if (timeOutEvent != null)
                {
                    Delegate[] list = timeOutEvent.GetInvocationList();
                    foreach (Delegate c in list)
                    {
                        //如果是窗体的,则Inovke实现
                        Control control = c.Target as Control;
                        if (control != null)
                        {
                            control.Invoke(c, new object[] {this, EventArgs.Empty });//如果有参数,可以在object[]{}括号里面
                        }
                        else c(this, EventArgs.Empty);
                    }
                }
            }        private void CheckLogin()
            { 
                //Check login here,if true, success
                if (SomeFuc(user, pwd))
                {
                    this.loginSucceed = true;
                }
                else loginSucceed = false;
                FireEvent();
            }
        }
    }
      

  8.   

    form类中有个 。 啥方法,忘记了,你查下MSDN。 好像是强制重绘控件机器所有子控件。
      

  9.   

    更正下代码,发现有错误,不允许
     /// <summary>
            /// 引发登陆操作完成的事件
            /// </summary>
            private void FireEvent()
            {
                if (timeOutEvent != null)
                {
                    Delegate[] list = timeOutEvent.GetInvocationList();
                    foreach (Delegate c in list)
                    {
                        //如果是窗体的,则Inovke实现
                        Control control = c.Target as Control;
                        if (control != null)
                        {
                            control.Invoke(c, new object[] {this, EventArgs.Empty });//如果有参数,可以在object[]{}括号里面
                        }
                        else timeOutEvent(this, EventArgs.Empty);
                    }
                }
            }
      

  10.   


    异步好了。例如这个csdn,你刚打开的时候它显示“游客”(其实可以显示“....正在登录”),过几秒钟才变成你的登录名。
      

  11.   

    通过连接SQL Server进行登录验证。
    终止线程的时候,需要比较长的一段时间,此时界面仍然假死。怎么回事啊?
      

  12.   


    无厘头。我的例子中不是已经开启了一个线程了吗,
     private void CheckLogin()
            { 
                //Check login here,if true, success
                if (SomeFuc(user, pwd))
                {
                    this.loginSucceed = true;
                }
                else loginSucceed = false;
                FireEvent();
            }
    这里不就是线程做的事情么。你的主界面已经空出来了,你想做什么 都可以了。
      

  13.   

    我知道开启了一个验证登录的线程啊,但当timer超时的时候,会终止loginThread线程,也就是执行loginThread.Abort();这句的时候卡好一会儿,此时界面仍是假死的,不知道怎么回事啊!
      

  14.   

    我还是给你解释下把:namespace WindowsFormsApplication1
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }        public event EventHandler timeOutEvent;//登陆操作的事件(包括超时、登陆失败或者成功)
            private System.Windows.Forms.Timer timer = null;//计时器,设置超时用的
            private string user = null;//额外数据,登陆用户名
            private string pwd = null;//额外数据,登陆用户的密码
            Thread loginThread = null;//登陆操作用的线程
            private bool loginSucceed = false;//登陆是否成功        //登陆按钮
            private void button1_Click(object sender, EventArgs e)
            {
                this.user = textBox1.Text;
                this.pwd = textBox2.Text;
                loginThread = new Thread(new ThreadStart(CheckLogin));
                loginThread.IsBackground = true;
                loginThread.Start();//登陆操作启用线程
                timer.Start();//开始计时
            }        private void Form1_Load(object sender, EventArgs e)
            {
                this.timeOutEvent += new EventHandler(LoginResult);
                timer = new System.Windows.Forms.Timer();
                timer.Interval = 10000;//设置10秒超时
                timer.Tick += new EventHandler(TimeOutEvent);
            }        private void LoginResult(object sender, EventArgs e)
            {
                this.label1.Text = loginSucceed ? "登陆成功" : "登陆失败";//这里是登陆成功或者失败后的结果
                if (loginSucceed)
                {
                    //验证成功后do something
                    MessageBox.Show("用户验证成功!");
                }
                else MessageBox.Show("用户名或者密码错误,或者连接超时!");//验证失败后 
            }        private void TimeOutEvent(object sender, EventArgs e)
            {
                timer.Stop();
                if (loginThread.IsAlive)
                {
                    loginThread.Abort();
                }            this.loginSucceed = false;
                FireEvent();//超时引发事件通知超时
            }        /// <summary>
            /// 引发登陆操作完成的事件
            /// </summary>
            private void FireEvent()
            {
                if (timeOutEvent != null)
                {
                    Delegate[] list = timeOutEvent.GetInvocationList();
                    foreach (Delegate c in list)
                    {
                        //如果是窗体的,则Inovke实现
                        Control control = c.Target as Control;
                        if (control != null)
                        {
                            control.Invoke(c, new object[] {this, EventArgs.Empty });//如果有参数,可以在object[]{}括号里面
                        }
                        else timeOutEvent(this, EventArgs.Empty);
                    }
                }
            }        //线程调用的方法,也就是你要验证用户的过程
            private void CheckLogin()
            { 
                if (SomeFuc(user, pwd))//把你的数据库操作写在这里,SomeFuc是一个模拟方法,具体实现你自己写
                {
                    this.loginSucceed = true;//验证成功
                }
                else loginSucceed = false;//验证失败
                FireEvent();//此处是线程启动的登陆操作完成,引发事件
            }
        }
    }
      

  15.   

    我这里测试了都是可以直接杀掉的,线程终止方法Abort();是通过引发异常来实现的,我知道为什么会卡在那里了。是无法引发异常,也就是你的操作是有问题的,相当于一个短期死循环过程了,根本过不了去终止,一直等在那里了。那不能用Abort()方法了。
      

  16.   

    验证的登录的时候会执行SqlHelper类中的一个执行存储过程的方法,如下:
    code=C#]
      public static DataSet RunProcedure(string storedProcName, IDataParameter[] parameters)
            {
                try
                {
                    using (SqlConnection connection = new SqlConnection(connectingstring))
                    {
                        DataSet dataSet = new DataSet();
                        connection.Open();
                        SqlDataAdapter sqlDA = new SqlDataAdapter();
                        sqlDA.SelectCommand = BuildQueryCommand(connection, storedProcName, parameters);
                        sqlDA.Fill(dataSet, "ds");
                        connection.Close();
                        return dataSet;
                    }
                }
                catch (Exception ex)
                {               
                    MessageBox.Show(ex.Message.ToString());
                    return null;
                }
    [/code]
      

  17.   


      public static DataSet RunProcedure(string storedProcName, IDataParameter[] parameters)
            {
                try
                {
                    using (SqlConnection connection = new SqlConnection(connectingstring))
                    {
                        DataSet dataSet = new DataSet();
                        connection.Open();
                        SqlDataAdapter sqlDA = new SqlDataAdapter();
                        sqlDA.SelectCommand = BuildQueryCommand(connection, storedProcName, parameters);
                        sqlDA.Fill(dataSet, "ds");
                        connection.Close();
                        return dataSet;
                    }
                }
                catch (Exception ex)
                {               
                    MessageBox.Show(ex.Message.ToString());
                    return null;
                }
      

  18.   

    这个很奇怪,一般来讲验证登陆是很快的,你要跑一个存储过程,而且这个存储过程居然那么耗时间。我的观点是要优化一下。 至于界面假死的现象,我只能说,不要用Abort方法来终止线程了,因为线程本身已经假死了。没法执行了。所以导致主线程也堵在那里了。 我做过一个项目就有这样变态的需求,是关于POS刷卡的,端口占用后,你不能直接杀线程(这里指的是托管线程),要终止刷卡,就必须杀掉线程,我们当时用的是非托管线程,用TerminateThread API来杀的,这样会导致资源不能释放,系统不稳定,所以我不推荐你用这种方式。你可以设置一个信号变量,比如,是因为超时引起的,线程就由它自己退出,退出时候根据信号变量来做判断。如果已经超时了就不要再提示了。如果没有超时就按照原来的方式执行,给出提示。还有就是,线程没有结束之前,屏蔽用户按下按钮引发事件。(假如存在资源不能多个执行占用的问题,像文件操作等)
      

  19.   

    你的是数据库操作,应该不存在占用(资源抢夺)的问题,多线程访问数据库资源应该是没有问题的。线程你让他自动退出,反正是后台线程。.net线程是自己释放资源的,所以不用担心
      

  20.   

    这个是很常见的,比如WebService调用就是这样的,如果服务器连接不上,要等很长时间。这一点,你只能尽可能的优化客户端的交互,无法避免啊。
      

  21.   

    你可以尝试用代码启用线程打开CMD,然后Ping 你的主机试试。如果100% loss,那么就提示连接服务器失败,完全是可行的。我们终端在调用C++的dll时候总是会出现奔溃的,怎么也找不出原因,可以肯定的是垃圾回收的问题,由于C++dll是别的公司开发的,我们没办法解决,只有通过CMD去调用包装好的.net dll,这样来操作,可以降低调用的频率,从而几乎解决奔溃的可能。
      

  22.   

    呵呵,虽然这个方法感觉很不舒服,但是确实是可以的,在老板面前不能说做不到,只能说暂时可行,等找到更好的解决方法之后再解决。我们的项目一直是这样用CMD调用一个exe执行来解决的,完成后释放掉。呵呵。今天有时间来逛逛,交流交流。~~~~