C# 线程安全的替代线程。允许浏览器在c中活动的睡眠#

C# 线程安全的替代线程。允许浏览器在c中活动的睡眠#,c#,winforms,multithreading,C#,Winforms,Multithreading,我需要一个简单的等待功能,允许浏览器事件处理,是线程安全的。一位同事说,在处理多个线程时,永远不要使用DoEvents 我注意到当我使用Thread.Sleep(10000)时我的浏览器活动暂停,直到睡眠完成 有人能推荐一个替代方案吗 下面是一些代码: public static int f_sleep(int time) { System.DateTime now = System.DateTime.Now; System.TimeSpan d

我需要一个简单的等待功能,允许浏览器事件处理,是线程安全的。一位同事说,在处理多个线程时,永远不要使用DoEvents

我注意到当我使用
Thread.Sleep(10000)时我的浏览器活动暂停,直到睡眠完成

有人能推荐一个替代方案吗

下面是一些代码:

    public static int f_sleep(int time)
    {

        System.DateTime now = System.DateTime.Now;
        System.TimeSpan duration = new System.TimeSpan(0, 0, 0, time);
        System.DateTime then = now.Add(duration);


        Thread this_thread = Thread.CurrentThread;
        while (then > DateTime.Now)
        {
            //MessageBox.Show("NewTime:" + then + "Now:" + DateTime.Now);
            //we do not want to use this because it's said to mess up multithreading
            Application.DoEvents();

            //Thread.CurrentThread.Sleep(10);
            Thread.Sleep(10);
        }           

        return 1;
    }

    private void f_run_selected_campaigns(object sender, EventArgs e)
    {
        jobs_datagrid.EndEdit();

        int count_active = 0;
        foreach (DataGridViewRow row in jobs_datagrid.Rows)
        {

            //MessageBox.Show(row.Cells[1].Value.ToString());
            if (row.Cells[1].Value.ToString() == "True")
            {
                count_active++;



                //troubleshooting
                Thread this_thread = new Thread(() =>
                    this.Invoke((MethodInvoker)delegate
                    {
                        test("hello");
                    }
                ));

                //threading properties
                this_thread.Name = "thread_" + row.Cells[0].Value.ToString();
                this_thread.IsBackground = true;
                this_thread.Start();

            }

        }

        if (count_active == 0)
        {
            MessageBox.Show("No campaigns are selected!");

        }
    }

    private void test(string this_string)
    {

        MessageBox.Show(this_string);
        //Thread.Sleep(1000);
        f_sleep(10); //for some reason Thread.Sleep does not work well with my browser loading waiting so I drew this up to create a temp pause in the code logic, but it's causing my threads to not run asychronously
        MessageBox.Show("Thread Done");
    }
我仍然找不到解决这个问题的办法。我认为有一种简单的方法可以暂停逻辑流,同时允许UI元素和webbrowser进行处理

现在,我正在使用这两个为我的处理需要,无论这是否会回来咬我当我多线程。。。我不知道

    private int WaitBrowserLoading(Control browser)
    {
        lock(_locker)
        {
            tabcontrol_browser.Invoke((MethodInvoker) delegate {
                for (int i = 0; i < 1000000; i++)
                {
                    if(((WebBrowser)browser).ReadyState != WebBrowserReadyState.Complete)
                    {
                        Application.DoEvents();
                        Thread.Sleep(10);
                    }else
                    {
                    break;
                    }
                } 

            });
            return 1;
        }

    }

    public static int f_sleep(int time)
    {
        System.DateTime now = System.DateTime.Now;
        System.TimeSpan duration = new System.TimeSpan(0, 0, 0, time);
        System.DateTime then = now.Add(duration);

        while (then > DateTime.Now)
        {
            Application.DoEvents();
            Thread.Sleep(10);
        }

        return 1;

    }
private int waitbrowser加载(控件浏览器)
{
锁(储物柜)
{
tabcontrol_browser.Invoke((MethodInvoker)委托{
对于(int i=0;i<1000000;i++)
{
if(((WebBrowser)browser.ReadyState!=WebBrowserReadyState.Complete)
{
Application.DoEvents();
睡眠(10);
}否则
{
打破
}
} 
});
返回1;
}
}
公共静态int f_睡眠(int时间)
{
System.DateTime now=System.DateTime.now;
System.TimeSpan持续时间=新System.TimeSpan(0,0,0,time);
System.DateTime then=now.Add(持续时间);
while(然后>DateTime.Now)
{
Application.DoEvents();
睡眠(10);
}
返回1;
}

如果您能够控制浏览器控件提供的内容,那么一件可能有效的事情就是延时重定向。为用户提供一个页面,其中包含一个无限循环的动画gif进度指示器,并包含以下内容:

<META HTTP-EQUIV="refresh" CONTENT="5;URL=my-next-page">


此页面将显示进度指示器,5秒后它将重定向到“我的下一页”。

如果您可以控制浏览器控件提供的内容,则可以使用延时重定向。为用户提供一个页面,其中包含一个无限循环的动画gif进度指示器,并包含以下内容:

<META HTTP-EQUIV="refresh" CONTENT="5;URL=my-next-page">


此页面将显示进度指示器,5秒钟后它将重定向到“我的下一页”。

这会有帮助吗?它只会阻止你的新线程

new Thread(() =>
{
    Thread.Sleep(10000);

    // do stuff
}).Start();

// and we're back, immediately

您也可以使用
任务
,但请确保等待的任务不会阻止其他任务。我的示例是“大锤式”强制启动新品牌的线程。

这会有帮助吗?它只会阻止你的新线程

new Thread(() =>
{
    Thread.Sleep(10000);

    // do stuff
}).Start();

// and we're back, immediately
您也可以使用
任务
,但请确保等待的任务不会阻止其他任务。我的示例是强制新品牌线程启动的“大锤方式”。

永远不要使用thread.Sleep()来等待其他线程完成

如果应用程序正在等待浏览器控件完成加载页面或url,则应在浏览器控件上挂起事件,以便它在加载完成时通知您。您没有说明正在使用什么浏览器控件,但查找名为“Loaded”或“PageLoaded”或“AfterNavigation”之类的事件

如果你的代码中有一系列的步骤,让浏览器加载一个特定的URL就在这些步骤的中间,你应该把剩下的步骤移到浏览器控件的页面加载事件处理程序中,以便在页面加载后执行它们。

< p>永远不要使用线程。 如果应用程序正在等待浏览器控件完成加载页面或url,则应在浏览器控件上挂起事件,以便它在加载完成时通知您。您没有说明正在使用什么浏览器控件,但查找名为“Loaded”或“PageLoaded”或“AfterNavigation”之类的事件


如果你的代码中有一系列的步骤,让浏览器加载一个特定的URL就在这些步骤的中间,你应该把剩下的步骤移到浏览器控件的页面加载事件处理程序中,以便在页面加载后执行这些操作。然后浏览器什么也做不了,因为UI线程只是在睡觉。我认为这是你的问题。

如果你做你的线程。在UI线程上睡眠,那么浏览器什么都做不了,因为UI线程只是在睡眠。我想这是你的问题。

我不确定你到底在找什么,但也许是:

System.Windows.Forms.Timer myTimer = new System.Windows.Forms.Timer();

public Form1()
{
    myTimer.Interval = 1000;
    myTimer.Tick += new EventHandler(myTimer_Tick);
    myTimer.Start();
    //Do stuff. 
}

void myTimer_Tick(object sender, EventArgs e)
{
    myTimer.Stop();
    //Do stuff when it ticks.
}

我不确定你到底在找什么,但也许是:

System.Windows.Forms.Timer myTimer = new System.Windows.Forms.Timer();

public Form1()
{
    myTimer.Interval = 1000;
    myTimer.Tick += new EventHandler(myTimer_Tick);
    myTimer.Start();
    //Do stuff. 
}

void myTimer_Tick(object sender, EventArgs e)
{
    myTimer.Stop();
    //Do stuff when it ticks.
}

最后,如果所有其他方法都失败,那么在调用DoEvents()时循环可能是一种选择。您需要阅读为什么这种方法不好,以及应该如何避免其不好。具体来说,当您的代码处于循环处理DoEvents()时,您应该主动抑制用户输入(读取和丢弃鼠标和键盘事件),否则应用程序的用户将能够与应用程序交互以调用菜单命令等,但您的应用程序在等待时不会处理这些命令。但是,在完成DoEvents()循环后,它将立即处理所有命令。您可能还需要担心其他事件(或者如果您不担心,那么您的应用程序将显得笨重),例如系统即将关闭的全局通知等。

最后,如果所有其他操作都失败,那么在调用DoEvents()时循环可能是一种选择。您需要阅读为什么这种方法不好,以及应该如何避免其不好。具体地说,当您的代码处于循环处理DoEvents()时,您应该主动抑制用户输入,(读取和丢弃鼠标和键盘事件,)o