honey the codewitch Ответов: 2

"Маршал" вызывает через контекст синхронизации наиболее легко?


У меня есть компонент, который хранит кэш на основе каждого потока, но в некоторых приложениях мне нужно разделить кэш между несколькими потоками.

Я не возражаю против размещения компонента в потоке, а затем маршалинга вызовов в/на этот поток, чтобы разделить кэш между другими потоками - на самом деле это мой план. Таким образом, он размещается в потоке а и получает доступ к B,C(и A) путем маршалирования всех вызовов из других потоков вплоть до A.

но мне нужно знать Самый простой способ, чтобы это произошло.

Я очень новичок в контекстах синхронизации в .NET.

Обычно то, что я делаю для выполнения погружения и размещения вызовов между потоками, - это ISynchronizeInvoke.Invoke/BeginInvoke

Проблема в том, что я не хочу оборачивать классы этого компонента. Существует 30 различных организаций, каждая из которых имеет множество членов.

Я знаю.Сеть может обернуть это для меня. Я знаю, что он может "маршалить" - даже если мне *придется* дать ему ISynchronizeInvoke или эквивелантный механизм где-то. Я сохраню одну, если понадобится.

Но как мне туда попасть?NET, чтобы обернуть вызовы для меня и маршаллировать их по потокам без необходимости вручную создавать оболочку?

Что я уже пробовал:

Я рассматривал возможность удаленного доступа к .NET, но это действительно тяжело и не совсем то, что я хочу.

Я хочу что-то inproc и относительно легкое. Я даже не знаю, где начать искать это. Мои поиски в google не дают мне того, что я хочу.

2 Ответов

Рейтинг:
1

honey the codewitch

такие вещи, как concurrentdictionary, - это не то, что я хочу. Я не собираюсь использовать синхронизированные словари. Я смотрю на боевые вызовы и погружаю их в определенный поток, надеюсь, с .NET, выполняющим маршалинг для меня, как это происходит с ISychronizeInvoke

Рейтинг:
0

George Swan

Вы можете использовать lock чтобы ограничить обновление переменной одним потоком за один раз. Другие потоки, вызывающие этот метод, будут заблокированы до тех пор, пока блокировка не будет снята.

private readonly object totalLock = new object();
private double total;
public void AdjustTotal(double amount)
{
    lock (totalLock)
    {
        total += amount;
    }

}

В качестве альтернативы вы можете использовать SemaphoreSlim класс для обеспечения той же функциональности без блокировки каких-либо потоков в процессе
private readonly SemaphoreSlim semaphoreSlim = new SemaphoreSlim(1);
private double total;
public async Task AdjustTotalAsync(double amount)
{
    await semaphoreSlim.WaitAsync();
    try
    {
        total += amount;
    }
    finally
    {
        //must release the lock
        semaphoreSlim.Release();
    }
}


honey the codewitch

К сожалению, я не могу заблокировать исходные классы, потому что они не мои.

Для этого мне пришлось бы делать обертки для каждого отдельного предмета.

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

George Swan

Не могли бы вы опубликовать какой-нибудь псевдокод с подробным описанием того, чего вы пытаетесь достичь, пожалуйста?

honey the codewitch

Не так легко, это много кода. Весь смысл этого упражнения в том, чтобы избежать необходимости писать его.

Если ты не получишь то, о чем я прошу, это будет совершенно круто. В любом случае я нашел другое решение, которое отодвигает всю эту проблему в сторону.

George Swan

Я рад, что вы решили свою проблему. Наилучшие пожелания.