Winfrm中如何判断如果if里的条件3秒没走,就走一遍,如果3秒内走了就不做处理

CSY_Admin 程序员  2017-12-10 10:52:36
大牛路过歇歇脚,帮帮忙,小弟感激不敬
...全文
649 25 点赞 打赏 收藏 举报
写回复
25 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
CSY_Admin 2017-12-12
引用 24 楼 daixf_csdn 的回复:
没法解释更多了,剩下的都是语法基础了,看来你timer还不会用,那就针对性的百度去,把专项知识补齐。总不能给你做个入门培训把。还得自己先掌握一定基础起来。
谢谢大佬的耐心教导,问题已解决,结贴给分
  • 打赏
  • 举报
回复
秋的红果实 2017-12-11
就是说如果3秒他还没加载完,我就再次加载请求他 ==> 3秒没做完的事,再从头开始?岂不是更慢?不解 判断有没有加载完,可以用一个变量 private bool isComplete=false; private xxxxx_DocumentCompleted(……) { 加载数据; //............................... isComplete=true; //代码能执行到这里,说明执行完了 } 可以让次线程调用DocumentCompleted方法,主线程做判断
  • 打赏
  • 举报
回复
圣殿骑士18 2017-12-11
没法解释更多了,剩下的都是语法基础了,看来你timer还不会用,那就针对性的百度去,把专项知识补齐。总不能给你做个入门培训把。还得自己先掌握一定基础起来。
  • 打赏
  • 举报
回复
圣殿骑士18 2017-12-11
引用 5 楼 CSY_Admin 的回复:
大佬写的代码就是精美,还有贴心的注释,感谢大佬! 这是我写的,目前还没发现有什么问题。大佬这样写是会提升效率吗,能说说您这样写的优点吗?您这样写的意思是开辟一个线程,当webbrowser加载指定的url成功时抓取数据,不成功时继续用新的线程加载吗?希望大佬能回复小弟,感激不尽
我只是全面考虑了你提出的所有问题,才写成这样。而且比较规范,具有可扩展性。而你这个写法似乎只实现你说的部分功能,没有实现 “就是说如果3秒他还没加载完,我就再次加载请求他”这点。 我的这个写法,确实也有p哥说的线程阻塞等问题,事件机制是最佳的机制。不过越精美的实现方案可能需要更多的代码拆分重构,做产品化可以朝这个方向努力,我这个实现以解决问题为先。
  • 打赏
  • 举报
回复
CSY_Admin 2017-12-11
引用 22 楼 CSY_Admin 的回复:
[quote=引用 21 楼 daixf_csdn 的回复:] 第一种方式的优化对你来说可能难度有点高,你可以采取第二种简单的方式。
嗯,好的,谢谢,你那个第二种方法中窗体加载事件中timer_Tick哪来的?[/quote] 我看到是这是个事件,
  • 打赏
  • 举报
回复
CSY_Admin 2017-12-11
引用 21 楼 daixf_csdn 的回复:
第一种方式的优化对你来说可能难度有点高,你可以采取第二种简单的方式。
嗯,好的,谢谢,你那个第二种方法中窗体加载事件中timer_Tick哪来的?
  • 打赏
  • 举报
回复
hhhhha123 2017-12-11
用定时器,然后看那段代码有没有走完,代码最后加个标记
  • 打赏
  • 举报
回复
不会用事件驱动设计的人,没有学过软件工程设计时,总是一遍遍轮询,是有多少事件就只知道去弄多少“线程+循环+阻塞”的思路来模拟事件。这是一个通病,要从这里开始起步,去学习事件驱动设计概念。
  • 打赏
  • 举报
回复
引用 2 楼 CSY_Admin 的回复:
大佬,情况是这样的,我在一个webbrowser的DocumentCompleted中判断当前请求是否加载完,加载完实施抓取并再次请求(因为请求过来的数据是动态的),就是说如果3秒他还没加载完,我就再次加载请求他(可能我的逻辑有点问题,请大佬指点一二),这个请求抓取的速度必须要快
当触发这个事件时,判断 ReadyState 是否是 WebBrowserReadyState.Complete,来判断是否“加载完”。 根本就不应该轮询。应该有个基于事件设计的概念。
  • 打赏
  • 举报
回复
定时的任务就作为定时器机制来处理,不要当作什么顺序“if代码”处理。设计思路最顶上的“帽子”是定时机制,而不是if语句。
  • 打赏
  • 举报
回复
圣殿骑士18 2017-12-11
第一种方式的优化对你来说可能难度有点高,你可以采取第二种简单的方式。
  • 打赏
  • 举报
回复
圣殿骑士18 2017-12-11
这不是一个完整的产品,细节我没有处理。程序正在处理中时,直接退出窗口,是会有这个问题。因为窗体已经销毁但线程还在执行,这种小bug你自己修复一下。
  • 打赏
  • 举报
回复
CSY_Admin 2017-12-11
引用 18 楼 daixf_csdn 的回复:
再给你一份用纯事件,无线程的实现方案,效果一模一样。
前面的方案,代码在两个方法中,这个方案代码分散到了5个方法中。我是更喜欢第一个,因为我在性能不是制约因素的前提下,更倾向于采用阅读性好的代码。
public partial class FormWebBrowser2 : Form
{
private int state = -1;
string url = "www.csdn.com";
private System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();

public FormWebBrowser2()
{
InitializeComponent();
}

private void FormWebBrowser2_Load(object sender, EventArgs e)
{
webBrowser1.ScriptErrorsSuppressed = true;


timer.Interval = 500; //可改成你要的3000ms
timer.Tick += timer_Tick;

StartNavigate();
}

private void StartNavigate()
{
webBrowser1.Navigate(url);
timer.Start();
state = -1;
}

void timer_Tick(object sender, EventArgs e)
{
if (state == -1)
{
timer.Stop();
webBrowser1.Stop();
label2.Text = (int.Parse(label2.Text) + 1).ToString(); //失败次数
webBrowser1.Navigate(url);
timer.Start();
}
}

private void button1_Click(object sender, EventArgs e)
{
StartNavigate();
}

private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
timer.Stop();

Thread.Sleep(200); //模拟提取数据
state = 1;
label1.Text = (int.Parse(label1.Text) + 1).ToString(); //成功次数

StartNavigate();
}

private void button2_Click(object sender, EventArgs e)
{
//测试
string url = "www.csdn.com";
webBrowser1.Navigate(url);
}
}

谢谢大佬,现在第一个方法出现了一个问题
  • 打赏
  • 举报
回复
圣殿骑士18 2017-12-11
再给你一份用纯事件,无线程的实现方案,效果一模一样。 前面的方案,代码在两个方法中,这个方案代码分散到了5个方法中。我是更喜欢第一个,因为我在性能不是制约因素的前提下,更倾向于采用阅读性好的代码。
public partial class FormWebBrowser2 : Form
    {
        private int state = -1;
        string url = "www.csdn.com";
        private System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();

        public FormWebBrowser2()
        {
            InitializeComponent();
        }

        private void FormWebBrowser2_Load(object sender, EventArgs e)
        {
            webBrowser1.ScriptErrorsSuppressed = true;
            

            timer.Interval = 500;     //可改成你要的3000ms
            timer.Tick += timer_Tick;

            StartNavigate();
        }

        private void StartNavigate()
        {
            webBrowser1.Navigate(url);
            timer.Start();
            state = -1;
        }

        void timer_Tick(object sender, EventArgs e)
        {
            if (state == -1)
            {
                timer.Stop();
                webBrowser1.Stop();
                label2.Text = (int.Parse(label2.Text) + 1).ToString();   //失败次数
                webBrowser1.Navigate(url);
                timer.Start();
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            StartNavigate();
        }

        private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
        {
            timer.Stop();

            Thread.Sleep(200);  //模拟提取数据
            state = 1;
            label1.Text = (int.Parse(label1.Text) + 1).ToString();   //成功次数

            StartNavigate();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            //测试
            string url = "www.csdn.com";
            webBrowser1.Navigate(url);
        }
    }
  • 打赏
  • 举报
回复
CSY_Admin 2017-12-11
引用 16 楼 daixf_csdn 的回复:
代码有了,注释有了,如果读不懂,那就没有讨论的基础了。代码就在那里,不至于读不懂吧,读不懂就把技术先补上。
小弟愚昧,已经懂了,谢谢大佬
  • 打赏
  • 举报
回复
圣殿骑士18 2017-12-11
代码有了,注释有了,如果读不懂,那就没有讨论的基础了。代码就在那里,不至于读不懂吧,读不懂就把技术先补上。
  • 打赏
  • 举报
回复
圣殿骑士18 2017-12-11
引用 13 楼 CSY_Admin 的回复:
[quote=引用 10 楼 daixf_csdn 的回复:] [quote=引用 5 楼 CSY_Admin 的回复:] 大佬写的代码就是精美,还有贴心的注释,感谢大佬! 这是我写的,目前还没发现有什么问题。大佬这样写是会提升效率吗,能说说您这样写的优点吗?您这样写的意思是开辟一个线程,当webbrowser加载指定的url成功时抓取数据,不成功时继续用新的线程加载吗?希望大佬能回复小弟,感激不尽
我只是全面考虑了你提出的所有问题,才写成这样。而且比较规范,具有可扩展性。而你这个写法似乎只实现你说的部分功能,没有实现 “就是说如果3秒他还没加载完,我就再次加载请求他”这点。 我的这个写法,确实也有p哥说的线程阻塞等问题,事件机制是最佳的机制。不过越精美的实现方案可能需要更多的代码拆分重构,做产品化可以朝这个方向努力,我这个实现以解决问题为先。[/quote] 不好意思,我前面可能没表述的太清楚,这个请求一般情况下测试是2-3秒就完成了,如果有其他原因导致它10秒还没完成我就重新加载它,因为整个请求抓取过程都是自动化的,所以我要保证程序不会中断。(而且速度要快)[/quote] 我提供的代码已经实现了你要的功能,你能指出哪里没实现吗?
  • 打赏
  • 举报
回复
CSY_Admin 2017-12-11
引用 4 楼 daixf_csdn 的回复:
尽量进行职责分离,逻辑会清楚一些。可以用子线程来访问和处理,主线程负责观察状态并发起访问线程。

public partial class FormWebBrowser : Form
{
private int state = -1;

public FormWebBrowser()
{
InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)
{
webBrowser1.ScriptErrorsSuppressed = true;
while (true)
{
if (state == 0)
{
//正在处理中则等待
Application.DoEvents();
continue;
}

Thread th = new Thread(new ThreadStart(() =>
{
int interval = 500; //可改成你要的3000ms
string url = "www.csdn.com";
//定时器:3000ms后未成功时标记状态为1
System.Threading.Timer timer = new System.Threading.Timer(new TimerCallback((s) =>
{
state = 1;
}), null, interval, System.Threading.Timeout.Infinite);

//访问url
webBrowser1.Invoke(new Action(() =>
{
webBrowser1.Navigate(url);
}));

//等待处理完毕
while (true)
{
if (state == 1)
{
//超时失败
webBrowser1.Invoke(new Action(() =>
{
webBrowser1.Stop();
label2.Text = (int.Parse(label2.Text) + 1).ToString(); //失败次数
}));
}

//成功或者失败时均退出
if (state == 1 || state == 2)
{
timer.Dispose();
break;
}
}
}));

//启动新的访问线程
state = 0;
th.Start();
}
}

private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
Thread.Sleep(200); //模拟提取数据
state = 2;
label1.Text = (int.Parse(label1.Text) + 1).ToString(); //成功次数
}

private void button2_Click(object sender, EventArgs e)
{
//测试
string url = "www.csdn.com";
webBrowser1.Navigate(url);
}
}


效果:

大佬写的代码就是精美,还有贴心的注释,感谢大佬!
这是我写的,目前还没发现有什么问题。大佬这样写是会提升效率吗,能说说您这样写的优点吗?您这样写的意思是开辟一个线程,当webbrowser加载指定的url成功时抓取数据,不成功时继续用新的线程加载吗?希望大佬能回复小弟,感激不尽
  • 打赏
  • 举报
回复
CSY_Admin 2017-12-11
引用 11 楼 From_TaiWan 的回复:
就是说如果3秒他还没加载完,我就再次加载请求他 ==> 3秒没做完的事,再从头开始?岂不是更慢?不解 判断有没有加载完,可以用一个变量 private bool isComplete=false; private xxxxx_DocumentCompleted(……) { 加载数据; //............................... isComplete=true; //代码能执行到这里,说明执行完了 } 可以让次线程调用DocumentCompleted方法,主线程做判断
这个请求一般情况下测试是2-3秒就完成了,如果有其他原因导致它10秒还没完成我就重新加载它,因为整个请求抓取过程都是自动化的,所以我要保证程序不会中断。(而且速度要快),3秒一般能加载完,就是如果加载不玩,要做处理,
  • 打赏
  • 举报
回复
CSY_Admin 2017-12-11
引用 10 楼 daixf_csdn 的回复:
[quote=引用 5 楼 CSY_Admin 的回复:] 大佬写的代码就是精美,还有贴心的注释,感谢大佬! 这是我写的,目前还没发现有什么问题。大佬这样写是会提升效率吗,能说说您这样写的优点吗?您这样写的意思是开辟一个线程,当webbrowser加载指定的url成功时抓取数据,不成功时继续用新的线程加载吗?希望大佬能回复小弟,感激不尽
我只是全面考虑了你提出的所有问题,才写成这样。而且比较规范,具有可扩展性。而你这个写法似乎只实现你说的部分功能,没有实现 “就是说如果3秒他还没加载完,我就再次加载请求他”这点。 我的这个写法,确实也有p哥说的线程阻塞等问题,事件机制是最佳的机制。不过越精美的实现方案可能需要更多的代码拆分重构,做产品化可以朝这个方向努力,我这个实现以解决问题为先。[/quote] 不好意思,我前面可能没表述的太清楚,这个请求一般情况下测试是2-3秒就完成了,如果有其他原因导致它10秒还没完成我就重新加载它,因为整个请求抓取过程都是自动化的,所以我要保证程序不会中断。(而且速度要快)
  • 打赏
  • 举报
回复
加载更多回复
相关推荐
发帖
C#
加入

10.6w+

社区成员

.NET技术 C#
申请成为版主
帖子事件
创建了帖子
2017-12-10 10:52
社区公告

让您成为最强悍的C#开发者