Как я могу достигнуть небесконечный, получают и отправляют тайм-ауты на сокете под Компактной Платформой?

Вместо нескольких if / else вы можете поместить все правило в массив для простоты поддержки.

$array = [
    1 => [
        4 => 'img/s1.jpg',
        12 => 'img/s12.jpg',
        14 => 'img/s14.jpg',
    ],
    2 => [
        2 => 'img/c2.jpg'
    ]
];
function getDayDateImage($array, $d, $h)
{
    while (!$array[$d][$h]) {
        $h--;
        if ($h < 0) {
            $h = 23;
            $d--;
        }
        if ($d < 1) {
            return 'img/rest.jpg'; // Default
        }
    }
    return $array[$d][$h];
}

echo getDayDateImage($array, 1, 1); // Get img/rest.jpg
echo getDayDateImage($array, 1, 13); // Get img/s12.jpg
echo getDayDateImage($array, 2, 1); // Get img/s14.jpg
echo getDayDateImage($array, 2, 4); // Get img/c2.jpg
//Just pass you $d and $h 
//getDayDateImage($array, $d, $h);

Надеюсь, что это поможет.

7
задан skolima 13 May 2009 в 15:26
поделиться

1 ответ

Этот код работает, увеличивая время ожидания, когда ожидалось (это модифицированная версия примера, который я связал в вопросе):

// copied from Mono, because CF lacks this enum
enum SocketError
{
    IOPending = 997,
    NoBufferSpaceAvailable = 10055,
    TimedOut = 10060,
    WouldBlock = 10035
}

// milliseconds
int receiveTimeout = 20000;
int sendTimeout = 20000;

public override int Read(byte[] buffer, int offset, int size)
{    
    int startTickCount = Environment.TickCount;
    int received = 0;
    do
    {
        List<Socket> sock = new List<Socket>(new Socket[] {socket});
        Socket.Select(sock, null, null, receiveTimeout*1000 + 1);
        if (Environment.TickCount > startTickCount + receiveTimeout)
            throw new SocketException((int) SocketError.TimedOut);
        try
        {
            received += socket.Receive(buffer, offset + received,
                size - received, SocketFlags.None);
        }
        catch (SocketException ex)
        {
            if (ex.ErrorCode == (int) SocketError.WouldBlock ||
                ex.ErrorCode == (int) SocketError.IOPending ||
                ex.ErrorCode == (int) SocketError.NoBufferSpaceAvailable)
            {
                // socket buffer is probably empty, wait and try again
                Thread.Sleep(30);
            }
            else
                throw; // any serious error occurr
        }
    } while (received < size);
    return received;
}

public override void Write(byte[] buffer, int offset, int size)
{
    int startTickCount = Environment.TickCount;
    int sent = 0;
    do
    {
        List<Socket> sock = new List<Socket>(new Socket[] {socket});
        Socket.Select(null, sock, null, sendTimeout*1000 + 1);
        if (Environment.TickCount > startTickCount + sendTimeout)
            throw new SocketException((int) SocketError.TimedOut);
        try
        {
            sent += socket.Send(buffer, offset + sent,
                size - sent, SocketFlags.None);
        }
        catch (SocketException ex)
        {
            if (ex.ErrorCode == (int) SocketError.WouldBlock ||
                ex.ErrorCode == (int) SocketError.IOPending ||
                ex.ErrorCode == (int) SocketError.NoBufferSpaceAvailable)
            {
                // socket buffer is probably full, wait and try again
                Thread.Sleep(30);
            }
            else
                throw; // any serious error occurr
        }
    } while (sent < size);
}

Ключевым элементом, отсутствующим в найденном мной примере, является Socket.Select (IList checkRead, IList checkWrite, IList checkError, int microSeconds) . Имейте в виду, что этот метод может изменять переданный ему список (поэтому мой код каждый раз создает новый) и измеряет время в микросекундах, а не в миллисекундах. И не забудьте использовать Environment.TickCount (который является источником монотонного времени ) вместо DateTime.Now для измерения времени.

9
ответ дан 7 December 2019 в 03:20
поделиться
Другие вопросы по тегам:

Похожие вопросы: