DateTime 멀티 스레딩 UDP Sender는 일정 루프에서 DateTime 개체의 값을 다시 할당 할 때 시간 결과가 매우 다릅니다.

손오공

요약 : 블록 간의 유일한 코드 차이점은 DateTime 개체의 할당과 재 할당입니다.

매우 재편성 "일정"에 따라 UDP 패킷을 보내는 앱이 있습니다. 타이머, 스레드 또는 다른 개념에 대해 큰 오해가 있다고 생각하게 만드는 일부 동작을보고 있습니다. SendingSchedule List를 기반으로 SendAllMessages () 메서드를 사용하여 패킷을 보내려고합니다. 내 전송 주파수는 12.5Hz 또는 각 메시지 버스트 사이의 지연 시간이 0.1 초 미만입니다. 그러나이 메서드의 루프 내에서 DateTime 개체를 다시 할당하면 훨씬 다른 값이 표시됩니다. 이 메서드는 4 개의 다른 작업에서 실행되므로 4 개의 다른 스레드에서 실행됩니다. 내 코드의 첫 번째 예제는 내가 원하고 기대하는 동작을 제공합니다. 거의 동시에 4 개의 패킷을 보낸 다음 .08 초 후에 4 개의 메시지가 또 다른 버스트를 봅니다. 코드의 두 번째 예는 훨씬 느린 속도로 메시지를 보여 주지만 이유를 이해합니다. 나는 둘 다 동일하게 행동 할 것이라고 생각했다. 두 번째 예제에서 내 "시간"개체가 스레드간에 공유되고 있습니까? 아니면 다른 일이 발생합니까?

WorkingCode (4 개의 메시지 버스트 후 다른 버스트 전에 .08 초 대기) :

private static void SendAllMessages(List<DataMessageFormat> dataMessageList, UDPSender udpSender, byte[] first4bytes, int messageSize, bool loopContinuously = false)
{
    // pass inetMessageList to DataMessageEncoder
    MessageDataEncoder dataMessageEncoder = new MessageDataEncoder();

    List<byte[]> byteArrayListDataMessage = dataMessageEncoder.ConvertFromFormatToByteArray(dataMessageList, first4bytes, messageSize, switchDefaultEndian);

    Console.WriteLine("Sending " +  first4bytes + " UDP Messages on Thread" + Thread.CurrentThread.ManagedThreadId);
    do
    {
        DateTime start = DateTime.Now;
        for (int i = 0; i < byteArrayListDataMessage.Count; i++) // all message lists must have the same count for this to work
        {
            DateTime time = start.AddSeconds(dataMessageEncoder.SendingSchedule[i]);
        Send:
            if (DateTime.Now > time)
            {
                udpSender.SendUDPOnce(byteArrayListDataMessage[i]);
            }
            else
            {
                System.Threading.Thread.Sleep(1);
                goto Send;
            }
        }
    } while (loopContinuously);
}

아래 코드는 스레드가 모두 동일한 DateTimeObject에서 대기하는 것처럼 거의 4 개의 메시지를 버스트하는 사이에 매우 긴 시간을 대기합니다.

   private static void SendAllMessages(List<DataMessageFormat> dataMessageList, UDPSender udpSender, byte[] first4bytes, int messageSize, bool loopContinuously = false)
{
    // pass inetMessageList to DataMessageEncoder
    MessageDataEncoder dataMessageEncoder = new MessageDataEncoder();

    List<byte[]> byteArrayListDataMessage = dataMessageEncoder.ConvertFromFormatToByteArray(dataMessageList, first4bytes, messageSize, switchDefaultEndian);

    Console.WriteLine("Sending " +  first4bytes + " UDP Messages on Thread" + Thread.CurrentThread.ManagedThreadId);
    do
    {
        DateTime time = DateTime.Now;
        for (int i = 0; i < byteArrayListDataMessage.Count; i++) // all message lists must have the same count for this to work
        {
            time = time.AddSeconds(dataMessageEncoder.SendingSchedule[i]);
        Send:
            if (DateTime.Now > time)
            {
                udpSender.SendUDPOnce(byteArrayListDataMessage[i]);
            }
            else
            {
                System.Threading.Thread.Sleep(1);
                goto Send;
            }
        }
    } while (loopContinuously);
}

아래는 wireshark의 스크린 샷을 생성하는 좋은 코드입니다. 좋은 타이밍 일명 첫 번째 코드 블록

아래는 wireshark의 스크린 샷을 생성하는 잘못된 코드입니다.

느린 타이밍 일명 두 번째 코드 블록

이 앱이 수행하는 작업에 대한 아이디어를 제공합니다. 콘솔 앱 간단한 1000 피트보기

C. 곤잘레스

두 코드 모두 논리가 다릅니다.

첫째 : 비교하는 시간 값은 초기 시간과 일정입니다. 원하는 시간에 도달하면 if테스트는 항상 참이되고 전체 byteArrayListDataMessage.Count요소 를 보냅니다 .

둘째 : for루프 의 모든 단계는 움직이는 타겟을 생성하므로 하나의 요소 만 전송됩니다.

이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.

침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

Related 관련 기사

뜨겁다태그

보관