C# 多线程冲突

C# 多线程冲突,c#,multithreading,C#,Multithreading,我的c#form运行两个线程,一个线程监听数据,另一个线程正在处理数据,以便我可以使用它。由于某种原因,一旦进程线程启动,侦听线程就不再执行 Thread th1 = new Thread(new ThreadStart(zeroMQConn.Listen)); th1.Start(); Thread th2 = new Thread(() => ProcessData(zeroMQConn)); th2.Start(); 当我调试它时,它启动th1进入它,然后th2启动,它再也不会回到

我的c#form运行两个线程,一个线程监听数据,另一个线程正在处理数据,以便我可以使用它。由于某种原因,一旦进程线程启动,侦听线程就不再执行

Thread th1 = new Thread(new ThreadStart(zeroMQConn.Listen));
th1.Start();
Thread th2 = new Thread(() => ProcessData(zeroMQConn));
th2.Start();
当我调试它时,它启动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;
    }
public void Listen()
{
while(true)
{
尝试
{
字节[]zmqBuffer=新字节[102400];
int消息长度;
lockForZMQ.EnterWriteLock();
messageLength=socket.Receive(zmqBuffer);
lockForZMQ.ExitWriteLock();
字节[]消息=新字节[messageLength];
BlockCopy(zmqBuffer,0,message,0,messageLength);
PriceBookData priceBook=PriceBookData.CreateBuilder().MergeFrom(message.Build();
double Type=priceBook.GetPb(0).QuoteType;
如果(类型==0.0)
{
lockForList.EnterWriteLock();
CachedBidBooks=价格手册;
lockForList.ExitWriteLock();
}
其他的
{
lockForList.EnterWriteLock();
CachedAskBooks=价格手册;
lockForList.ExitWriteLock();
}
}
捕获(ZmqException ex)
{
MessageBox.Show(例如Message);
}
}
}
public void ProcessData(对象连接)
{
while(true)
{
priceBookData=((ZeroMQClass)连接).GetPriceBook();
}
}
公共列表GetPriceBook()
{
List AskAndBid=新列表();
lockForList.EnterWriteLock();
if(CachedAskBooks!=null&&CachedBidBooks!=null)
{
AskAndBid.Add(cachedbidbook);
AskAndBid.Add(CachedAskBooks);
cachedbidbook=null;
CachedAskBooks=null;
lockForList.ExitWriteLock();
退还投标书;
}
lockForList.ExitWriteLock();
返回null;
}

这里提供的是生产者-消费者模型,但您没有正确地同步它们。问题在于,您没有准备好处理的某种缓冲区或数据集合,而是有一个变量,并且完全同步对该变量的访问。这意味着生产者永远不能在消费者工作时工作

无论何时处理生产者/消费者队列,
BlockingCollection
都是一个很棒的类

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);
var queue=newblockingcollection();
Task.Factory.StartNew(()=>
{
while(true)
{
字节[]zmqBuffer=新字节[102400];
int消息长度;
socket.Receive(zmqBuffer);
字节[]消息=新字节[messageLength];
BlockCopy(zmqBuffer,0,message,0,messageLength);
PriceBookData priceBook=PriceBookData.CreateBuilder().MergeFrom(message.Build();
double Type=priceBook.GetPb(0).QuoteType;
添加(价格手册);
}
},TaskCreationOptions.LongRunning);
Task.Factory.StartNew(()=>
{
foreach(队列中的变量项。GetConsumingEnumerable())
{
//处理物品
}
},TaskCreationOptions.LongRunning);

这里提供的是生产者-消费者模型,但您没有正确地同步它们。问题在于,您没有准备好处理的某种缓冲区或数据集合,而是有一个变量,并且完全同步对该变量的访问。这意味着生产者永远不能在消费者工作时工作

无论何时处理生产者/消费者队列,
BlockingCollection
都是一个很棒的类

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);
var queue=newblockingcollection();
Task.Factory.StartNew(()=>
{
while(true)
{
字节[]zmqBuffer=新字节[102400];
int消息长度;
socket.Receive(zmqBuffer);
字节[]消息=新字节[messageLength];
BlockCopy(zmqBuffer,0,message,0,messageLength);
PriceBookData priceBook=PriceBookData.CreateBuilder().MergeFrom(message.Build();
double Type=priceBook.GetPb(0).QuoteType;
添加(价格手册);
}
},TaskCreationOptions.LongRunning);
Task.Factory.StartNew(()=>
{
foreach(队列中的变量项。GetConsumingEnumerable())
{
//处理物品
}
},TaskCreationOptions.LongRunning);

您需要为这两种线程方法提供代码。无需在自己的线程中执行此操作即可更新结果。使用数据绑定将视图与数据绑定,您只需在th2中更新数据源,UI线程就会自动更新视图。@David关于这个问题的任何内容都与UI无关。它完全是在访问数据并在数据到达UI层之前对其进行操作,假设UI层已经存在。那么,
ProcessData
的意义是什么呢?您只需设置变量,从不使用它做任何事情;从表面上看,你一直在循环,从来没有做过任何有成效的事情。processdata调用一个函数,将价格手册放入列表中,这样我就可以在我的另一个类中访问它们。listen和getpricebook在一个sperate类中,而不是进程数据。您需要为这两个线程方法提供代码。无需在您自己的线程上执行此操作来更新结果。使用数据绑定将视图与数据绑定,您只需在th2中更新数据源,UI线程就会自动更新视图。@David关于这个问题的任何内容都与UI无关。它完全是在访问数据并在数据到达UI层之前对其进行操作,假设UI层已经存在。那么,
ProcessData
的意义是什么呢?您只需设置变量,从不使用它做任何事情;所以你一直在循环