苏飞论坛

 找回密码
 马上注册

QQ登录

只需一步,快速开始

分布式系统框架(V2.0) 轻松承载百亿数据,千万流量!讨论专区 - 源码下载 - 官方教程

HttpHelper爬虫框架(V2.7-含.netcore) HttpHelper官方出品,爬虫框架讨论区 - 源码下载 - 在线测试和代码生成

HttpHelper爬虫类(V2.0) 开源的爬虫类,支持多种模式和属性 源码 - 代码生成器 - 讨论区 - 教程- 例子

查看: 12109|回复: 11

[其他] 如何实现窗体等待输入然后继续执行

[复制链接]
发表于 2014-1-22 14:48:01 | 显示全部楼层 |阅读模式
本帖最后由 huoshan12345 于 2014-1-22 15:57 编辑

我做了一个qq登录程序,点击登陆后对列表中的每一个qq执行登陆函数,如果对于其中的一个qq需要输入验证码,则暂停登陆,等待用户输入验证码后,然后继续登陆

我按照百度到的方法(下面的链接),套用了一下,结果出问题了,主窗体被锁住了,根本没办法输入
http://www.cnblogs.com/Fooo/archive/2008/12/27/1363619.html

[C#] 纯文本查看 复制代码
    public partial class MainForm : Form
    {
        public WQQHelper wqq = null;
        List<WQQHelper> WQQList = new List<WQQHelper>();

        public MQQHelper mqq = null;
        List<MQQHelper> MQQList = new List<MQQHelper>();

        private delegate void DLogin();
        AutoResetEvent VerifyCodeInputed = new AutoResetEvent(false);

        private void button_Login_Click(object sender, EventArgs e)
        {//点击登陆后
            Thread th = new Thread(new ThreadStart(Login));
            th.IsBackground = true;
            th.Start();
        }

        private void Login()
        {//登陆函数
            if (this.InvokeRequired)
            {
                DLogin d = new DLogin(Login);
                this.Invoke(d);                                                return;
            }

            foreach (WQQHelper wqq in WQQList)
            {
                if (wqq.status.statusType != Status.StatusType.Offline)
                {
                    continue;
                }

                textBox_VerifyCode.Text = "";
                int index = listView_QQList.FindItemWithText(wqq.Number).Index;
                listView_QQList.Items[index].Selected = true;
                listView_QQList.Items[index].Focused = true;

                Status status = wqq.Login(null);
                if (status.statusType == Status.StatusType.LoginSuccessd)
                {
                    new KeepAliveTrigger(wqq);
                    listView_QQList.Items[index].SubItems[4].Text = wqq.LoginMethod;
                }
                else if (status.statusType == Status.StatusType.NeedVerify)
                {
                    listView_QQList.Items[index].SubItems[4].Text = "需要验证码";
                    this.pictureBox_VerifyPic.Image = wqq.GetVerifyImage();
                    VerifyCodeInputed.WaitOne();                      // 等候输入验证码

                    this.wqq.Login(textBox_VerifyCode.Text);
                    listView_QQList.Items[index].SubItems[4].Text = status.StatusInfo;
                }
                else
                {
                    listView_QQList.Items[index].SubItems[4].Text = status.StatusInfo;
                }
            }
        }

        private void textBox_VerifyCode_TextChanged(object sender, EventArgs e)
        {
            if (textBox_VerifyCode.Text.Length == 5)
            {
                VerifyCodeInputed.Set();   // 当输入的文本为5位,发一个通知
            }
        }
    }
}


如果变成下面的这个样子,那么整个界面上的所有按钮都不能点了,文本框无法输入,表现的就像是锁住了一样 新建位图图像.jpg




小程序测试:功能,先点击计算,然后输入,当输入的文本超过4位时,在输出中显示输入的内容
新建位图图像.jpg


[C#] 纯文本查看 复制代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;


namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        private delegate void DLogin();

        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Thread th = new Thread(YourThread);
            th.Start();
            
        }

        private void textBox1_TextChanged(object sender, EventArgs e)
        {
            if (textBox1.Text.Length >= 4)
            {
                detailCollectedEvent.Set();                      // 当textBox1的文本超过4位,发一个通知
            }
        }

        AutoResetEvent detailCollectedEvent = new AutoResetEvent(false);

        void YourThread()
        {
            detailCollectedEvent.WaitOne();                      // 等候通知     
            textBox2.Text = textBox1.Text;
        }
    }
}









1. 开通SVIP会员,免费下载本站所有源码,不限次数据,不限时间
2. 加官方QQ群,加官方微信群获取更多资源和帮助
3. 找站长苏飞做网站、商城、CRM、小程序、App、爬虫相关、项目外包等点这里
发表于 2014-1-22 14:59:55 | 显示全部楼层
[C#] 纯文本查看 复制代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using DotNet.Utilities;
using System.IO;
using System.Text.RegularExpressions;
using System.Net;
using System.Runtime.Serialization.Json;
using System.Runtime.InteropServices;
using System.Threading;

namespace Winfrom
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Thread th = new Thread(YourThread);
            th.Start();
        }

        private void textBox1_TextChanged(object sender, EventArgs e)
        {
            if (textBox1.Text.Length >= 4)
            {
                detailCollectedEvent.Set();                      // 当textBox1的文本超过4位,发一个通知
            }
        }

        AutoResetEvent detailCollectedEvent = new AutoResetEvent(false);
        void YourThread()
        {
            detailCollectedEvent.WaitOne();                      // 等候通知
            textBox1.Text = "123456";
        }

    }

   

}

正常的啊,你说的锁住是什么情况,
是不是没有出验证码啊,
子线程不为影响主线程吧。
 楼主| 发表于 2014-1-22 15:18:35 | 显示全部楼层
站长苏飞 发表于 2014-1-22 14:59
[mw_shl_code=csharp,true]using System;
using System.Collections.Generic;
using System.ComponentMod ...

不知道是不是委托的问题,可是如果不使用委托的话,又会有跨线程访问的异常
发表于 2014-1-22 15:27:25 | 显示全部楼层
用这种方法开线程就不需要委托了
[C#] 纯文本查看 复制代码
 Thread objThread = new Thread(new ThreadStart(delegate
            {
                ThreadMethodTxt(Convert.ToInt32(textBox1.Text.Trim()));
            }));
            objThread.Start();
 楼主| 发表于 2014-1-22 15:34:07 | 显示全部楼层
站长苏飞 发表于 2014-1-22 15:27
用这种方法开线程就不需要委托了[mw_shl_code=csharp,true] Thread objThread = new Thread(new ThreadStar ...

这样会发生这个异常:
线程间操作无效: 从不是创建控件“listView_QQList”的线程访问它。
发表于 2014-1-22 15:35:40 | 显示全部楼层
用委托也没有关系吧,你能个最简单的先测试好,再加上你的程序,我刚看发上的代码是经过我测试 的是正常的。我用提net4.0
 楼主| 发表于 2014-1-22 15:59:12 | 显示全部楼层
站长苏飞 发表于 2014-1-22 15:35
用委托也没有关系吧,你能个最简单的先测试好,再加上你的程序,我刚看发上的代码是经过我测试 的是正常的 ...

飞哥再看一下,我写了一个小测试程序,不使用委托会出现异常:
线程间操作无效: 从不是创建控件的线程访问它。

如果使用委托,那么窗体就不能输入了
发表于 2014-1-22 16:01:18 | 显示全部楼层
我上面的程序就是经过测试的呀。C#2.0+Net4.0没有问题,2.0Net我知道肯定有问题,你贴下主要代码你刚写的例子
 楼主| 发表于 2014-1-22 16:05:15 | 显示全部楼层
站长苏飞 发表于 2014-1-22 16:01
我上面的程序就是经过测试的呀。C#2.0+Net4.0没有问题,2.0Net我知道肯定有问题,你贴下主要代码你刚写的例 ...

已经贴了,就在1楼,我重新编辑了帖子
发表于 2014-1-22 16:15:15 | 显示全部楼层
你写的方法中就没有看到用委托啊,而且你的写法也有问题
我参考下我的
[C#] 纯文本查看 复制代码
 public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        private delegate void setText(string msg);
        private setText settext;

        private void button1_Click(object sender, EventArgs e)
        {
            Thread objThread = new Thread(new ThreadStart(delegate
            {
                YourThread();
            }));
            objThread.Start();

            settext = new setText(setTextbox);
        }

        private void textBox1_TextChanged(object sender, EventArgs e)
        {
            if (textBox1.Text.Length >= 4)
            {
                detailCollectedEvent.Set();                      // 当textBox1的文本超过4位,发一个通知
            }
        }
        public void setTextbox(string msg)
        {
            textBox1.Text = msg;
        }
        AutoResetEvent detailCollectedEvent = new AutoResetEvent(false);
        void YourThread()
        {
            for (int i = 0; i < 3; i++)
            {
                this.BeginInvoke(settext, "开始");
                detailCollectedEvent.WaitOne();                      // 等候通知
                this.BeginInvoke(settext, "输入正确" + i.ToString());
            }
        }

    }

这样我测试过2.0和4.0都是正常的
您需要登录后才可以回帖 登录 | 马上注册

本版积分规则

QQ|手机版|小黑屋|手机版|联系我们|关于我们|广告合作|苏飞论坛 ( 豫ICP备18043678号-2)

GMT+8, 2025-1-4 12:56

© 2014-2021

快速回复 返回顶部 返回列表