C# 单独同步两个线程队列并阻止执行?

C# 单独同步两个线程队列并阻止执行?,c#,.net,multithreading,queue,blocking,C#,.net,Multithreading,Queue,Blocking,我正在开发一个应用程序,它在用户可自定义的时间间隔内生成多个线程,以便从{此处插入任何类型的服务}检索数据。我的应用程序使用CMD脚本(即使Windows spawn conhost)有时映射网络驱动器,然后它们按自定义间隔休眠并重复。我们叫他们柜台吧 到目前为止还不错,但是有一些过程不能异步运行(例如映射驱动器),所以我必须为一些特定的线程创建某种队列,这样程序才能正常运行 到目前为止,我已经能够通过在这里找到的生产者/消费者队列博客帖子->实现它。这在CMD计数器中起作用,因此应用程序不会像

我正在开发一个应用程序,它在用户可自定义的时间间隔内生成多个线程,以便从{此处插入任何类型的服务}检索数据。我的应用程序使用CMD脚本(即使Windows spawn conhost)有时映射网络驱动器,然后它们按自定义间隔休眠并重复。我们叫他们柜台吧

到目前为止还不错,但是有一些过程不能异步运行(例如映射驱动器),所以我必须为一些特定的线程创建某种队列,这样程序才能正常运行

到目前为止,我已经能够通过在这里找到的生产者/消费者队列博客帖子->实现它。这在CMD计数器中起作用,因此应用程序不会像7821678321一样生成conhosts并阻止PC,我正在对它们排队。无论如何,这不是我遇到的问题

当我需要映射网络驱动器以运行某些命令并取消映射,然后让下一个线程执行时,就会出现问题。让我更清楚地说明这个问题:

线程类型A:只需排队(仅A型),无需等待B型线程执行或完成其执行。这实际上是用教程中的代码完成的

线程类型B:其他B类型线程需要等待当前B类型线程完成其执行

我在考虑对B型线程使用相同的教程,但我意识到我不能使用它,因为其他线程一直在调用它们自己,直到它被解除阻塞,并且调用它们自己会重新映射驱动器,它不会工作(啊,我可以看到驱动器是否被映射,但看不到它映射到哪里……我可以,但我想避免编写不必要的代码)

我做了家庭作业,浏览了谷歌,甚至制作了一个小应用程序来尝试我的练习,在C#中使用lock关键字,但没有成功,即使该函数阻塞了其他线程,它们仍在调用阻塞函数,我不希望:(

有很多教程,但没有一个是简明的,足以让我理解它们的。我在SO中发现了一些问题,但它们大多与java相关,我在C#4.0中工作

好的,这是我写的代码。如果你运行它,你会注意到其他线程将调用阻塞函数。我不希望在调用它的第一个线程完成之前调用该函数。或者这样做,或者创建某种队列,但也要避免由于其他线程执行其进程所花费的时间而使队列自行填满

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace ThreadTest
{
    public class BlockObj
    {
        Object lockObj = new Object();

        public void DoBlock(int id)
        {
            lock (lockObj)
            {
                Console.WriteLine("Counter " + id + " locking object created, wait 5 sec");
                Thread.Sleep(5000);
                Console.WriteLine("Stuff done, keep going");
            }
        }
    }

    class Program
    {
        static Random r = new Random(DateTime.Now.Second);
        static BlockObj oo = new BlockObj();

        public static void Counter(object id)
        {
            int i = (int)id;
            while (true)
            {
                Thread.Sleep(1000 * r.Next(1, 10));
                Console.WriteLine("Counter " + i + " call blocking stuff...");
                oo.DoBlock(i);
                Console.WriteLine("Counter " + i + " finish work");
            }
        }

        public static void Main(string[] args)
        {
            for (int i = 0; i < 5; i++)
            {
                Thread t = new Thread(new ParameterizedThreadStart(Counter));
                t.Start(i);
            }
        }
    }
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用系统线程;
命名空间线程测试
{
公共类BlockObj
{
Object lockObj=新对象();
公共无效数据块(内部id)
{
锁(lockObj)
{
Console.WriteLine(“计数器”+id+“已创建锁定对象,请等待5秒”);
睡眠(5000);
WriteLine(“完成了,继续”);
}
}
}
班级计划
{
静态随机r=新随机(DateTime.Now.Second);
静态BlockObj oo=新BlockObj();
公共静态无效计数器(对象id)
{
int i=(int)id;
while(true)
{
睡眠(1000*r.Next(1,10));
控制台.WriteLine(“计数器”+i+“呼叫阻塞…”);
多布洛克(i);
控制台写入线(“计数器”+i+“完成工作”);
}
}
公共静态void Main(字符串[]args)
{
对于(int i=0;i<5;i++)
{
线程t=新线程(新参数化线程启动(计数器));
t、 启动(i);
}
}
}
}

实际上,我希望看到一些应用程序的概念验证代码,它将生成两个线程队列,这些队列中的线程将等待当前线程完成执行,然后再运行下一个线程。但是,每个队列都有自己的阻塞。线程队列1不应阻塞线程队列2的执行,反之亦然。

Ok是的,我只是用自己的代码解决了它,尝试了一些东西,直到成功:)

对于那些想要同步、简单队列的人,这里是:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Collections;
using System.Runtime.Remoting.Messaging;

namespace TheadingPool1
{
    // http://www.c-sharpcorner.com/UploadFile/mgold/QueueInThread11222005232529PM/QueueInThread.aspx

    public class ThreadQueue
    {
        private Queue _qOrder = new Queue();
        private Queue _qSync;
        private Thread _qThread;
        private ManualResetEvent _eWait = new ManualResetEvent(false);

        private int _wait;

        public ThreadQueue(int w)
        {
            _wait = w;
            _qSync = Queue.Synchronized(_qOrder);
        }

        public void Start()
        {
            _qThread = new Thread(new ThreadStart(Process));
            _qThread.IsBackground = true;
            _qThread.Start();
        }

        public void Process()
        {
            Random x = new Random(DateTime.Now.Second);
            object item;
            while (true)
            {
                item = null;
                lock (_qSync.SyncRoot)
                {
                    if (_qSync.Count > 0)
                    {
                        item = (object)_qSync.Dequeue();
                    }
                    else
                    {
                        _eWait.Reset();
                    }
                }
                if (item != null)
                {
                    Console.WriteLine("[" + _wait + "] [" + item.ToString() + "] :D");
                    Thread.Sleep(_wait * x.Next(1, 5));
                }
                else
                {
                    _eWait.WaitOne();
                }
            }
        }

        public void Enqueue(object obj)
        {
            _qSync.Enqueue(obj);
            _eWait.Set();
        }
    }

    public class Program
    {
        private static ThreadQueue _q1 = new ThreadQueue(10);
        private static ThreadQueue _q2 = new ThreadQueue(50);

        public static void Main(string[] args)
        {
            _q1.Start();
            _q2.Start();

            for (int i = 0; i < 50; i++)
                _q1.Enqueue(i);

            for (int i = 0; i < 50; i++)
                _q2.Enqueue(i);

            while (true)
            {
                Thread.Sleep(100);
            }
        }
    }
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用系统线程;
使用系统集合;
使用System.Runtime.Remoting.Messaging;
名称空间定义池1
{
// http://www.c-sharpcorner.com/UploadFile/mgold/QueueInThread11222005232529PM/QueueInThread.aspx
公共类线程队列
{
专用队列_qOrder=新队列();
专用队列同步;
私有线程_qThread;
private ManualResetEvent _eWait=新的ManualResetEvent(错误);
私人国际等待;
公共线程队列(int w)
{
_等待=w;
_qSync=Queue.Synchronized(_qOrder);
}
公开作废开始()
{
_qThread=新线程(新线程开始(进程));
_qThread.IsBackground=true;
_qThread.Start();
}
公共程序()
{
Random x=新随机数(DateTime.Now.Second);
目标项目;
while(true)
{
item=null;
锁(qSync.SyncRoot)
{
如果(qSync.Count>0)
{
item=(object)qSync.Dequeue();
}
其他的
{
_eWait.Reset();
}
}
如果(项!=null)
{
Console.WriteLine(“[”+_wait+“][“+item.ToString()+”]:D”);
Sleep(_wait*x.Next(1,5));
}
其他的
{