简体   繁体   English

多线程冲突

[英]Multithreading Conflicts

I have my c# form running two threads one thread listens for data to come in and the other is processing the data so i can use it. 我有运行两个线程的C#表单,一个线程侦听要传入的数据,另一个正在处理数据,以便我可以使用它。 for some reason once the process thread starts the listen thread isn't executed any more. 由于某种原因,一旦进程线程启动了侦听线程,就不再执行。

Thread th1 = new Thread(new ThreadStart(zeroMQConn.Listen));
th1.Start();
Thread th2 = new Thread(() => ProcessData(zeroMQConn));
th2.Start();

when i debug this it starts the th1 goes into it and then th2 starts and it never goes back to th1 and my data comes back null. 当我调试它时,它开始进入th1,然后进入th2,它再也回到不了th1,而我的数据又返回null。

public void Listen()
    {
        while (true)
        {
            try
            {
                byte[] zmqBuffer = new byte[102400];
                int messageLength;
                lockForZMQ.EnterWriteLock();
                messageLength = socket.Receive(zmqBuffer);
                lockForZMQ.ExitWriteLock();
                byte[] message = new byte[messageLength];
                Buffer.BlockCopy(zmqBuffer, 0, message, 0, messageLength);
                PriceBookData priceBook = PriceBookData.CreateBuilder().MergeFrom(message).Build();
                double Type = priceBook.GetPb(0).QuoteType;
                if (Type == 0.0)
                {
                    lockForList.EnterWriteLock();
                    CachedBidBooks = priceBook;
                    lockForList.ExitWriteLock();
                }
                else
                {
                    lockForList.EnterWriteLock();
                    CachedAskBooks = priceBook;
                    lockForList.ExitWriteLock();
                }
            }
            catch (ZmqException ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
    }

 public void ProcessData(object connection)
    {
        while (true)
        {
            priceBookData = ((ZeroMQClass)connection).GetPriceBook();
        }

    }

 public List<PriceBookData> GetPriceBook()
    {
        List<PriceBookData> AskAndBid = new List<PriceBookData>();
        lockForList.EnterWriteLock();
        if (CachedAskBooks != null && CachedBidBooks != null)
        {
            AskAndBid.Add(CachedBidBooks);
            AskAndBid.Add(CachedAskBooks);
            CachedBidBooks = null;
            CachedAskBooks = null;
            lockForList.ExitWriteLock();
            return AskAndBid;
        }
        lockForList.ExitWriteLock();
        return null;
    }

What you have here is a producer-consumer model, but you aren't properly synchronizing them. 这里拥有的是生产者-消费者模型,但是您没有正确同步它们。 The problem is that rather than some sort of buffer or collection of data that's ready to be processed, you have a single variable, and you completely synchronize access to that variable. 问题在于,您只有一个变量,而不是完全准备好要处理的某种缓冲区或数据集合,而是完全同步了对该变量的访问。 This means that the producer can't ever be working while the consumer is working. 这意味着生产者永远无法在消费者工作时工作。

The BlockingCollection<T> is a fantastic class whenever dealing with producer/consumer queues. 每当处理生产者/消费者队列时, BlockingCollection<T>是一个很棒的类。

var queue = new BlockingCollection<PriceBookData>();

Task.Factory.StartNew(() =>
{
    while (true)
    {
        byte[] zmqBuffer = new byte[102400];
        int messageLength;
        socket.Receive(zmqBuffer);
        byte[] message = new byte[messageLength];
        Buffer.BlockCopy(zmqBuffer, 0, message, 0, messageLength);
        PriceBookData priceBook = PriceBookData.CreateBuilder().MergeFrom(message).Build();
        double Type = priceBook.GetPb(0).QuoteType;
        queue.Add(priceBook);
    }
}, TaskCreationOptions.LongRunning);

Task.Factory.StartNew(() =>
{
    foreach (var item in queue.GetConsumingEnumerable())
    {
        //do stuff with item
    }
}, TaskCreationOptions.LongRunning);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM