多线程中的c#数据处理不正确

多线程中的c#数据处理不正确,c#,multithreading,winforms,C#,Multithreading,Winforms,我有一个产品下拉列表,选择产品连接到websocket并获取该产品的提要消息。一旦(1)feed消息开始出现,我必须(2)获取订单簿,然后(3)处理feed消息。因此,第一个和最后一个任务将异步运行。为此,我编写了以下代码: void OnReceivingFeedMessage() { concurrentQueue.Enqueue(message); if (!messageStreamStarted) // only first time get order bo

我有一个产品下拉列表,选择产品连接到websocket并获取该产品的提要消息。一旦(1)feed消息开始出现,我必须(2)获取订单簿,然后(3)处理feed消息。因此,第一个和最后一个任务将异步运行。为此,我编写了以下代码:

void OnReceivingFeedMessage()
{
     concurrentQueue.Enqueue(message);

     if (!messageStreamStarted)   // only first time get order book
     {
         messageStreamStarted = true;
         GetOrderBookData();
     }
}

private void GetOrderBookData()
{
    MarketData m = new MarketData();
    ProductOrderBook p = m.GetProductOrderBook(productId);           
    bidsList = p.bids;
    asksList = p.asks;
    isOrderBookUpdated = true;

    Task task3 = Task.Run(() => KickStartToProcessQueue());         
}

private void KickStartToProcessQueue()
{
    while (threadProcessQueueExist)
    {
        int recordCountNew = concurrentQueue.Count();
        if (recordCountNew != 0)
        {
            if (isOrderBookUpdated)
            {
                ProcessQueueMessages();
            }
        }
    }
}

private void ProcessQueueMessages()
{
    if (!concurrentQueue.IsEmpty)
    {
        string jsonString;
        while (concurrentQueue.TryDequeue(out jsonString))
        {
          // have to insert the record in existing order book
        }
     }
}
这是第一次完美地工作。但是,当我更换产品并重新连接时,事情变得一团糟,数据处理不当。写在product selectedindex上的代码会发生更改

private void CloseAndReconnectToGetWebsocketFeed()
{ 
    w.CloseWebsocketConnection();                 
    messageStreamStarted = false;            
    isOrderBookUpdated = false;
    ConcurrentQueue<string> wssMessagesQueue = new ConcurrentQueue<string>();
    concurrentQueue = wssMessagesQueue;

    ConnectAndGetWebsocketFeedMessages(); // this calls OnReceivingFeedMessage
}
private void closeandconnecttogetWebsocketfeed()
{ 
w、 CloseWebsocketConnection();
messageStreamStarted=false;
isOrderBookUpdated=false;
ConcurrentQueue wssMessagesQueue=新ConcurrentQueue();
concurrentQueue=wssMessagesQueue;
ConnectAndGetWebsocketFeedMessages();//这将调用ReceivingFeedMessage
}
我是多线程新手,所以不确定是否需要使用lock、async/await或其他方法。在上面的代码中我做错了什么


第一次运行时运行良好,但当我更换产品并再次执行相同的处理时,它开始出现问题。有人能告诉我,在一遍又一遍地执行相同的步骤之前,我如何清除所有的资源吗?我认为您正在编写不必要的复杂代码。我不是100%确定,你的问题是什么,但这里有一些东西可能会帮助你

使用
BlockingCollection
使用该类,您可以停止您的消费者线程,直到收到新消息。下面是一个简单的例子,说明这些东西是如何工作的:

BlockingCollection<string> collection = new BlockingCollection<string>(new ConcurrentQueue<string>());
Task t = Task.Run(() =>
{
    while (collection.TryTake(out string item, Timeout.Infinite))
    {
        Console.WriteLine($"Started reading {item}...");
        Thread.Sleep(1000); //simulate intense work
        Console.WriteLine($"Done reading {item}");
    }
});
while (true)
{
    //This could be your OnReceivingFeedMessage()
    string input = Console.ReadLine();
    if (input == "stop")
    {
        Console.WriteLine("Stopping...");
        collection.CompleteAdding();
        break;
    }
    else
    {
        collection.Add(input);
    }
}
t.Wait();
这还有一个优点(或缺点),即任务都是并行运行的。这意味着你不能依赖于他们的工作顺序,但他们会处理得更快

顺便说一句:这两种方法都有一个优点,那就是你不用忙着等待。根据你的问题:

while (threadProcessQueueExist)
{
    int recordCountNew = concurrentQueue.Count();
    if (recordCountNew != 0)
    {
        if (isOrderBookUpdated)
        {
            ProcessQueueMessages();
        }
    }
}

只要队列中没有任何内容,这段代码就会创建忙等待,这意味着处理器的一个核心将处于非常高的负载,而实际上什么也不做。这被认为是一种不好的做法。

您的代码似乎过于复杂。我的理解是否正确,您希望在消息传入时立即(并行)处理消息?并且在新消息传入时立即中止处理旧消息?否,我想在收到邮件后尽快收到订单,一旦收到订单,我就必须处理邮件。因此,首先是消息,然后是订单簿,然后是处理。项目将不断出现并添加到队列中。一旦收到订单簿,我们需要处理队列中已经保存的消息和队列中出现的新消息
while (threadProcessQueueExist)
{
    int recordCountNew = concurrentQueue.Count();
    if (recordCountNew != 0)
    {
        if (isOrderBookUpdated)
        {
            ProcessQueueMessages();
        }
    }
}