Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/282.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#排队时System.InvalidOperation异常_C# - Fatal编程技术网

c#排队时System.InvalidOperation异常

c#排队时System.InvalidOperation异常,c#,C#,我试图构建一个队列,在API给出生命迹象后将数据发送到API 以下代码中的System.InvalidOperationException: private void sendHandler() { while (true) { if (!sendQueueActive && sendQueue.Count >= 1) { sendQueueActive

我试图构建一个队列,在API给出生命迹象后将数据发送到API

以下代码中的System.InvalidOperationException:

 private void sendHandler()
    {
        while (true)
        {
            if (!sendQueueActive && sendQueue.Count >= 1)
            {
                sendQueueActive = true;
                foreach (relays relays in sendQueue)
                {                        
                    dynamic result = IoLogikApiConnector.put("io/relay", relays);
                    int code = result.error.code;
                    if (code != 0)
                    {
                        _log.logErrorToApi("Cannot write to IoLogik", "Error code:" + result, _deviceID);
                        _device.logErrorToApi();
                        sendQueue.Remove(relays);
                    }
                    else
                    {

                        _device.logConnectedToApi();
                        sendQueue.Remove(relays);
                    }
                    sendQueueActive = false;

                }
            }
            else
            {
                Thread.Sleep(20);
            }
        }
    }

您正在使用foreach从队列中删除项目。从来都不是好事

最好写

using System.Linq;
using System.Collections.Generic;
using System.Collections;

private void sendHandler()
{
    while (true)
    {
        if (!sendQueueActive && sendQueue.Count >= 1)
        {
            sendQueueActive = true;

            // MAKE A COPY FIRST
            var sendQueueCopy = sendQueue.ToList();

            foreach (relays relays in sendQueueCopy)
            {                        
                dynamic result = IoLogikApiConnector.put("io/relay", relays);
                int code = result.error.code;
                if (code != 0)
                {
                    _log.logErrorToApi("Cannot write to IoLogik", "Error code:" + result, _deviceID);
                    _device.logErrorToApi();
                    sendQueue.Remove(relays);
                }
                else
                {

                    _device.logConnectedToApi();
                    sendQueue.Remove(relays);
                }
                sendQueueActive = false;

            }
        }
        else
        {
            Thread.Sleep(20);
        }
    }
}
但最好使用线程安全队列

下面是上面链接中的剪切粘贴示例

        // A bounded collection. It can hold no more 
        // than 100 items at once.
        BlockingCollection<Data> dataItems = new BlockingCollection<Data>(100);


        // A simple blocking consumer with no cancellation.
        Task.Run(() => 
        {
            while (!dataItems.IsCompleted)
            {

                Data data = null;
                // Blocks if number.Count == 0
                // IOE means that Take() was called on a completed collection.
                // Some other thread can call CompleteAdding after we pass the
                // IsCompleted check but before we call Take. 
                // In this example, we can simply catch the exception since the 
                // loop will break on the next iteration.
                try
                {
                    data = dataItems.Take();
                }
                catch (InvalidOperationException) { }

                if (data != null)
                {
                    Process(data);
                }
            }
            Console.WriteLine("\r\nNo more items to take.");
        });

        // A simple blocking producer with no cancellation.
        Task.Run(() =>
        {
            while (moreItemsToAdd)
            {
                Data data = GetData();
                // Blocks if numbers.Count == dataItems.BoundedCapacity
                dataItems.Add(data);
            }
            // Let consumer know we are done.
            dataItems.CompleteAdding();
        });
//一个有界集合。它再也装不下了
//一次超过100件物品。
BlockingCollection数据项=新BlockingCollection(100);
//一个没有取消的简单阻塞消费者。
Task.Run(()=>
{
而(!dataItems.IsCompleted)
{
数据=空;
//如果number.Count==0,则阻塞
//IOE表示对已完成的集合调用了Take()。
//其他线程可以在我们通过后调用CompleteAdding
//我已完成支票,但在我们打电话之前。
//在本例中,我们可以简单地捕获异常,因为
//循环将在下一次迭代中中断。
尝试
{
data=dataItems.Take();
}
捕获(无效操作异常){}
如果(数据!=null)
{
过程(数据);
}
}
Console.WriteLine(“\r\n没有更多的项目要获取。”);
});
//一个简单的阻塞生产者没有取消。
Task.Run(()=>
{
while(moreItemsToAdd)
{
Data=GetData();
//如果numbers.Count==dataItems.BoundedCapacity,则阻止
添加(数据);
}
//让消费者知道我们已经完成了。
dataItems.CompleteAdding();
});

那么,以下代码中的哪一个。。?异常消息是什么?在foreach循环中,程序正在向列表写入数据,而此代码希望删除队列列表中的“中继”。sendQueue的类型是什么?
Queue
上没有
Remove
方法。它是一个自定义对象的列表。如果是由于在foreach循环中删除集合中的项(可能是这样),则异常消息会告诉您确切的问题。始终检查该选项。谢谢,但sendQueue.ToList()不可用;不可用?sendQueue的具体类型是什么??我假设它应该实现
IEnumerable
它是一个包含object的列表。您可以显示声明吗。它来自哪个库/命名空间。
使用System.Collections.Generic;私有列表sendQueue=新列表()