0

我在 Windows 窗体 C# 应用程序上的多线程应用程序有问题。该应用程序在多核机器上运行良好,但是当它在单核机器上运行时,所有线程都挂起。我正在使用backgroundWorker,代码如下:

 class custonTime // delay class
 {
     public void sleep_sec(int sleep)
     {
         int time_now = Environment.TickCount;
         int time_sleep = sleep;
         while ((Environment.TickCount - time_now) < time_sleep) ;
     }
 }

当我按下 UI 上的按钮时,标志actiondoAlways设置为true并启动以下后台工作程序。backgorundworker1 等待并在正确的时间触发任务,另一个执行任务:

 private void backgroundWorker2_DoWork(object sender, DoWorkEventArgs e)
 {
     while(action)
     {
         if(doItAlways)
         {
             //do important tasks
         }
         if(task1)
         { 
             //do things
             task1 = false;
         }
         if(task2)
         { 
             //do things
             task1 = false;
         }
    }
}

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
    task1=true;
    manegerTimewr2.sleep_sec(12000);//call delay class to wait 12 secs
    task2=true;
    manegerTimewr2.sleep_sec(12000);//call delay class to wait 12 secs
}

我的延迟类锁不仅是我backgorundworker1的,而且backgroundworker2也是,使得不可能执行 flag 触发的任务doItAlways,应用程序仅在 while 循环完成时才被释放。

它只发生在单核机器上。

还有其他方法吗?一种直接而简单的方法来挂起一个线程直到经过一段时间而不阻塞其他线程?

注意Thread.Sleep不会起作用,因为不同机器上经过的时间变化太大。

4

3 回答 3

0

使用此方法实现等待指定时间量:Thread.Sleep

于 2013-08-31T15:42:45.610 回答
0

而不是使用 a BackgroundWorker,而是启动一个新的Thread,并ThreadPriority手动为该线程设置 。然后你就可以使用它了Thread.Sleep,它应该更精确地工作,因为线程具有更高的优先级。以下是您最终应该得到的结果:

void Run()
{
    // some initialization stuff
    new Thread(DoWork1) { Priority = ThreadPriority.AboveNormal }.Start();
    new Thread(DoWork2) { Priority = ThreadPriority.Highest }.Start();
}

private void DoWork2()
{
    while (action)
    {
        if (doItAlways)
        {
            //do important tasks
        }
        if (task1)
        {
            //do things
            task1 = false;
        }
        if (task2)
        {
            //do things
            task1 = false;
        }
        Thread.Sleep(1);
    }
}

private void DoWork1()
{
    task1 = true;
    Thread.Sleep(12000);//call delay class to wait 12 secs
    task2 = true;
    Thread.Sleep(12000);//call delay class to wait 12 secs
}
于 2013-08-31T16:13:53.223 回答
0

问题是,在BackgroundWorker内部使用线程池,它通常包含与机器上的 CPU/内核相同数量的线程。因此,在单 CPU 机器上,您将只有一个线程处理 BackgroundWorker,我猜它们是按顺序安排的,因此第一个运行两个sleep_sec调用,然后才开始第二个调用。

另一方面,在多核机器上,线程池中有更多线程,因此它可以按预期工作。

您可以为“等待”使用“正常” Thread(与 一起Thread.Sleep,不要使用while循环),因为这不需要任何 UI 交互。您也可以只使用一个Timer对象,这正是为此目的(在指定的时间后触发一个事件)。

于 2013-08-31T16:11:22.037 回答