Показать сообщение отдельно
Старый 01.03.2015, 13:13   #3
pax
Unity/C# кодер
 
Аватар для pax
 
Регистрация: 03.10.2005
Адрес: Россия, Рязань
Сообщений: 7,568
Написано 3,006 полезных сообщений
(для 5,323 пользователей)
Ответ: Асинхронная очередь

Мне вроде удалось решить мою задачу с помощью Interlocked.Exchange
private int _writing;
        
readonly Queue<NetMessage_sendQueue = new Queue<NetMessage>();

        
// посылаю сообщение
        
public void Send(NetMessage msg)
        {
            if (
msg.sended) throw new InvalidOperationException("Message already sended!");

            
msg.sended true;

            
// добавляю сообщение в очередь
            
Enqueue(msg);

        }

        
// добавление в очередь
        
internal void Enqueue(NetMessage msg)
        {
            
lock (_sendQueue)
            {
                
_sendQueue.Enqueue(msg);
            }

            
SendNext();
        }

        private 
void OnEndWrite(IAsyncResult ar)
        {
            
NetworkStream.EndWrite(ar);
            
Interlocked.Exchange(ref _writing0);
            
SendNext();
        }

        
byte[] _sendBuffer = new byte[1024];
        
readonly List<NetMessage_messagesToSend = new List<NetMessage>();

        
internal bool SendNext()
        {
            var 
current Interlocked.Exchange(ref _writing1);

            if (
current == 0// если нет отправки, отправляю
            
{
                
int countBytesToSend 0;
                
int countMesagesToSend 0;

                
lock (_sendQueue)
                {
                    
_messagesToSend.Clear();

                    while (
_sendQueue.Count 0)
                    {
                        var 
msg _sendQueue.Dequeue();
                        
_messagesToSend.Add(msg);
                        
countMesagesToSend++;
                        
countBytesToSend += msg.SizeToSend;
                        if (
countBytesToSend 1024 32)
                        {
                            break;
                        }
                    }
                }


                if (
countBytesToSend 0)
                {
                    if (
_sendBuffer.Length countBytesToSend)
                    {
                        Array.
Resize(ref _sendBuffercountBytesToSend);
                    }

                    var 
pos 0;

                    for (
int i 0_messagesToSend.Counti++)
                    {
                        var 
msg _messagesToSend[i];
                        Array.
Copy(msg.data0_sendBufferposmsg.SizeToSend);
                        
pos += msg.SizeToSend;
                    }
                    
NetworkStream.BeginWrite(_sendBuffer0posOnEndWritenull);
                }
                else
                {
                    
// нечего слать, значит ничего не отправляю и отправки нет
                    
Interlocked.Exchange(ref _writing0);
                }
            }

            return 
false;
        } 
__________________
Blitz3d to Unity Wiki
(Offline)
 
Ответить с цитированием
Эти 3 пользователя(ей) сказали Спасибо pax за это полезное сообщение:
Igor (01.03.2015), Mr_F_ (01.03.2015), St_AnGer (02.03.2015)