Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/svg/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用.NET3.0什么是线程恢复和挂起的好替代品_C#_Multithreading_Synchronization_.net 3.0 - Fatal编程技术网

C# 使用.NET3.0什么是线程恢复和挂起的好替代品

C# 使用.NET3.0什么是线程恢复和挂起的好替代品,c#,multithreading,synchronization,.net-3.0,C#,Multithreading,Synchronization,.net 3.0,我仅限于.NET3.0:这是外部强加的要求 我需要处理Generic.Queue中的字符串。主线程将使字符串排队,工作线程将使字符串排队,然后对其进行处理。在工作线程的顶部,它挂起自身并等待在有东西进入队列时恢复。然后,它会在每个项目退出队列时清空队列进程,然后在队列为空时挂起自身 我创建了一个小示例程序,简洁地说明了基本逻辑。我知道排队-出列需要保护,但它们在这里是原始的,因为这不是我调查的重点 我研究了使用信号量和互斥对象,但按照我对文档的理解,似乎没有一种方法可以在不等待的情况下向事件发送

我仅限于.NET3.0:这是外部强加的要求

我需要处理Generic.Queue中的字符串。主线程将使字符串排队,工作线程将使字符串排队,然后对其进行处理。在工作线程的顶部,它挂起自身并等待在有东西进入队列时恢复。然后,它会在每个项目退出队列时清空队列进程,然后在队列为空时挂起自身

我创建了一个小示例程序,简洁地说明了基本逻辑。我知道排队-出列需要保护,但它们在这里是原始的,因为这不是我调查的重点

我研究了使用信号量和互斥对象,但按照我对文档的理解,似乎没有一种方法可以在不等待的情况下向事件发送信号。我想让resume在工作线程被阻塞时解除阻塞,以便它可以在队列中循环。此信号仅在主线程将和项添加到队列时发生。如果工人已经在工作,那么它将继续工作,直到队列为空。只有当工人被抓到并等待做某事时,才需要发出信号启动工人

using System;
using System.Collections.Generic;
using System.Threading;

namespace QueueProcessor
{
    class Program
    {
        static Queue<string> _Messages = new Queue<string>();
        static bool _Continue = true;
        static Thread _DequeueThread = null;

        static void Main( string[] args )
        {
            _DequeueThread = new Thread( DequeueThread );
            _DequeueThread.Start();
            for(;;)
            {
                Console.WriteLine( "Entersomething here:");
                string something = Console.ReadLine();
                if( something.Equals("quit") )
                {
                    _Continue = false;
                    ResumeThread();
                    break;
                }
                _Messages.Enqueue( something );
                ResumeThread();
            }
        }

        static void ResumeThread( )
        {
            try
            {
                _DequeueThread.Resume();  // .NET 3.0 is the limit
            }
            // If it is already resumed, the frame work throws an exception.
            // This seem unneccesary since if it is already resumed then what's the bother?
            catch( ThreadStateException ) 
            {
                Console.WriteLine( "Thread already running....." );
            }
        }

        static void SuspendThread()
        {
            _DequeueThread.Suspend(); // .NET 3.0 is the limit
        }

        static void DequeueThread()
        {
            Random randomTime = new Random();
            while( _Continue )
            {
                SuspendThread();
                while( _Messages.Count > 0)
                {
                    string message = _Messages.Dequeue();
                    Console.WriteLine( String.Format ( "Dequeue:{0}", message ) );
                    int timeout = randomTime.Next();
                    timeout %= 4000;
                    Thread.Sleep(timeout); // simulated taking a while to process message
                }
            }
        }
    }
}

这是完整的答案。谢谢你Alexi为我指明了正确的方向

using System;
using System.Collections.Generic;
using System.Threading;

namespace QueueProcessor
{

    class Program
    {
        static Queue<string> _Messages = new Queue<string>();
        static bool _Continue = true;
        static Thread _DequeueThread = null;
        static AutoResetEvent _Latch = null;

        static void Main( string[] args )
        {
            _DequeueThread = new Thread( DequeueThread );
            _Latch = new AutoResetEvent(false);
            _DequeueThread.Start();
            for(;;)
            {
                Console.WriteLine( "Entersomething here:");
                string something = Console.ReadLine();
                if( something.Equals("quit") )
                {
                    _Continue = false;
                    ResumeThread();
                    break;
                }
                lock( _Messages )
                {
                    _Messages.Enqueue( something );
                }
                ResumeThread();
            }
        }

        static void ResumeThread( )
        {
            _Latch.Set();
        }

        static void SuspendThread()
        {
            _Latch.WaitOne();
        }

        static void DequeueThread()
        {
            Random randomTime = new Random();
            while( _Continue )
            {
                SuspendThread();
                string message = string.Empty;
                for(;;)
                {
                    lock ( _Messages )
                    {
                        message = _Messages.Count == 0 ? string.Empty : _Messages.Dequeue();
                    }

                    if( String.IsNullOrEmpty( message ) ) break; // Loop exit condition

                    Console.WriteLine( String.Format ( "Dequeue:{0}", message ) );
                    int timeout = randomTime.Next();
                    timeout %= 4000;
                    Thread.Sleep(timeout); // simulated taking a while to process message
                }
            }
        }
    }
}

对不起,我还想指出,编译器告诉我Resume和Suspend是折旧的。我想更换这些电话,但我不确定什么才是好的替代品。您正在寻找事件。。。不知道为什么您没有查看源代码以了解ConcurrentQueue是如何实现的,或者您确实查看了,但忘记了在帖子中添加注释。谢谢Alexei。AutoResetEvent是我正在寻找的。我仅限于.NET 3.0:这是外部强加的要求。。我希望你是在收取额外费用,因为这一限制显然会给你带来更多的工作。请注意,.NET版本与此完全无关。对于所有应用程序,无论.NET与否,从同一进程中异步挂起线程都是完全错误的。相关的Win32 API供调试器使用,而不是供通用同步使用。