Существует ли класс синхронизации, которые гарантируют порядок FIFO в C#?

Не совсем так. Но они очень похожи. Наиболее очевидное отличие состоит в том, что в C # лямбда-выражение может идти куда угодно, где у вас может быть значение, которое оказывается функцией; в Ruby у вас есть только один блок кода на вызов метода.

Они оба заимствовали идею из Lisp (язык программирования, датируемый концом 1950-х годов), который, в свою очередь, заимствовал лямбда-концепцию из Лямбда-исчисления Чёрча , изобретенного в 1930-х годах.

15
задан Ahmed Said 13 June 2009 в 08:58
поделиться

5 ответов

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

using System.Threading;

public sealed class QueuedLock
{
    private object innerLock;
    private volatile int ticketsCount = 0;
    private volatile int ticketToRide = 1;

    public QueuedLock()
    {
        innerLock = new Object();
    }

    public void Enter()
    {
        int myTicket = Interlocked.Increment(ref ticketsCount);
        Monitor.Enter(innerLock);
        while (true)
        {

            if (myTicket == ticketToRide)
            {
                return;
            }
            else
            {
                Monitor.Wait(innerLock);
            }
        }
    }

    public void Exit()
    {
        Interlocked.Increment(ref ticketToRide);
        Monitor.PulseAll(innerLock);
        Monitor.Exit(innerLock);
    }
}

Пример использования:

QueuedLock queuedLock = new QueuedLock();

try
{
   queuedLock.Enter();
   // here code which needs to be synchronized
   // in correct order
}
finally
{
    queuedLock.Exit();
}

Источник через кеш Google

31
ответ дан 1 December 2019 в 00:16
поделиться

Нет гарантированного порядка для любых встроенных объектов синхронизации: http://msdn.microsoft.com/en-us/library/ms684266 (VS.85) .aspx

Если вам нужен гарантированный порядок, вам придется попробовать построить что-то самостоятельно, но обратите внимание, что это не так просто, как может показаться, особенно когда несколько потоков достигают точки синхронизации в одно и то же время (почти одновременно). В некоторой степени порядок, в котором они будут выпущены, всегда будет «случайным», так как вы не можете предсказать, в каком порядке будет достигнута точка, так имеет ли это значение?

но он отмечает, что блокировки были сделаны намеренно несправедливыми в последних выпусках Windows, чтобы улучшить масштабируемость и уменьшить конвои блокировок .

Вам определенно нужна блокировка по FIFO? Может быть, есть другой подход к проблеме. Я не знаю ни одной блокировки в .NET, которая гарантированно была бы FIFO.

11
ответ дан 1 December 2019 в 00:16
поделиться

You should re-design your system to not rely on the execution order of the threads. For example, rather than have your threads make a DB call that might take more than one second, have your threads place the command they would execute into a data structure like a queue (or a heap if there is something that says "this one should be before another one"). Then, in spare time, drain the queue and do your db inserts one at a time in the proper order.

7
ответ дан 1 December 2019 в 00:16
поделиться

Нет гарантированного порядка для любых встроенных объектов синхронизации: http://msdn.microsoft.com/en-us/library/ms684266(VS.85).aspx

Если вам нужен гарантированный порядок, вам придется попробовать что-то построить самостоятельно, но обратите внимание, что это не так как бы просто это ни звучало, особенно когда несколько потоков достигают точки синхронизации (почти одновременно). В некоторой степени порядок их выпуска всегда будет «случайным».

1
ответ дан 1 December 2019 в 00:16
поделиться

На самом деле ответы хорошие, но я решил проблему, удалив таймер и запустив метод (ранее обработчик таймера) в фоновом потоке следующим образом

    private void InsertBasicVaraibles()
    {
         int functionStopwatch = 0;
         while(true)
         {

           try
           {
             functionStopwatch = Environment.TickCount;
             DataTablesMutex.WaitOne();//mutex for my shared resources
             //insert into DB 
           }
           catch (Exception ex)
           {
             //Handle            
           }
           finally            
           {                
              DataTablesMutex.ReleaseMutex();
           }

           //simulate the timer tick value
           functionStopwatch = Environment.TickCount - functionStopwatch;
           int diff = INSERTION_PERIOD - functionStopwatch;
           int sleep = diff >= 0 ?  diff:0;
           Thread.Sleep(sleep);
        }
    }
1
ответ дан 1 December 2019 в 00:16
поделиться
Другие вопросы по тегам:

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