C# 在多线程应用程序窗体c上使用while循环锁定#阻塞单核机器上的所有线程

C# 在多线程应用程序窗体c上使用while循环锁定#阻塞单核机器上的所有线程,c#,multithreading,winforms,C#,Multithreading,Winforms,我在windows form C#应用程序上的多线程应用程序出现问题。该应用程序在多核机器上运行良好,但在单核机器上运行时,所有线程都挂起。我正在使用backgroundWorker,代码如下: class custonTime // delay class { public void sleep_sec(int sleep) { int time_now = Environment.TickCount; int time_sleep

我在windows form 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) ;
     }
 }
我的延迟类锁不仅锁定了我的
backgorundworker1
,还锁定了
backgroundworker2
,使得无法执行由标志
doItAlways
触发的任务,应用程序仅在while循环完成时才被释放

它只发生在单核机器上

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


注意
线程。睡眠将不起作用,因为在不同的机器上所用的时间差异太大。使用此方法执行指定的等待时间:。

问题是,
BackgroundWorker
在内部使用一个线程池,其中包含的线程数通常与计算机上的CPU/内核数相同。因此,在单CPU机器上,您将只有一个线程处理BackgroundWorkers,我猜他们是按顺序安排的,因此第一个线程运行两个
sleep\u sec
调用,只有在这之后,第二个线程才会启动

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


您可以使用“普通”
线程
(与
线程.Sleep
,而不使用
while
循环)进行“等待”,因为这不需要任何UI交互。您也可以只使用一个
计时器
对象,该对象正好用于此目的(在指定的时间后触发事件)。

而不是使用
BackgroundWorker
,而是启动一个新的
线程
,并手动设置该线程的
线程优先级
。然后,您将能够使用
线程。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
}

像这样一个非常紧密的环。。。而((Environment.TickCount-time\u now)TimeSpan.TicksPerSecond
,如果它要在所有可能的.NET实现上都使用相同的代码。您还应该查看.NET和TPL中的各种计时器类,将其作为管理任务的更好方法。
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
}