Можно ли использовать Singleton Class внутри DLL для разных процессов?

Я создаю настраиваемую аппаратную инфраструктуру .net, которая будет использоваться другими программистами для управления некоторым оборудованием. Они добавят ссылку на нашу DLL, чтобы перейти к нашей аппаратной платформе. Мне нужен общий класс, к которому можно получить доступ из нескольких приложений (процессов).

Синтаксический шаблон, похоже, мне нужен, но он работает только для нескольких потоков внутри вашего процесса. Я мог быть совершенно неправ, но вот пример кода С#, который у меня есть. Я не могу не чувствовать, что дизайн неправильный. Хотел бы я поделиться более конкретной информацией, но я не могу.

  • Я должен подчеркнуть, что я не буду контролировать приложение клиента. Решение должно содержаться внутри самой структуры (DLL).

Рамка: (общая библиотека DLL)

public class Resources
{
    static readonly Resources m_instance = new Resources();

    public string Data;

    private Resources()
    {
        Data = DateTime.Now.ToString();
    }

    public static Resources Instance
    {
        get
        {
            return m_instance;
        }
    }
} 

Приложение для тестирования: (в конечном итоге клиентское приложение)

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("Press enter to capture the resource!");
        Console.ReadLine();

        var resources = Resources.Instance;
        Console.WriteLine("\r\n{0}: {1}\r\n", Thread.CurrentThread.ManagedThreadId, resources.Data);

        BackgroundWorker worker = new BackgroundWorker();
        worker.DoWork += WorkerDoWork;
        worker.RunWorkerAsync();

        while (worker.IsBusy)
        {
            Thread.Sleep(100);
        }

        Console.WriteLine("Press enter to close the process!");
        Console.ReadLine();
    }

    static void WorkerDoWork(object sender, DoWorkEventArgs e)
    {
        var resources = Resources.Instance;
        Console.WriteLine("\r\n{0}: {1}\r\n", Thread.CurrentThread.ManagedThreadId, resources.Data);
    }
}

Первое запущенное приложение дает результат:

Нажмите Enter, чтобы захватить ресурс!

1: 6/24/2009 8:27:34 AM

3: 6/24/2009 8:27:34 AM

Нажмите "Enter", чтобы закрыть процесс!

Второе приложение дает вывод:

Нажмите Enter, чтобы захватить ресурс!

9: 6/24/2009 8:27:35 AM

10: 6/24/2009 8:27:35 AM

Нажмите "Enter", чтобы закрыть процесс!

Заключение

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

Как вы видите, singleton работает для нескольких потоков внутри процесса, но не для перекрестных процессов. Возможно, этого не может быть сделано, поскольку я не могу найти какое-либо решение.

Ответ 1

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

Ответ 2

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

Самые популярные технологии, которые позволяют вам обмениваться своим объектом довольно прямо, - Remoting и WCF.

Предоставление примера совместного использования одного из них с любым из них выходит за рамки ответа SO. Но для каждого из них есть много учебников в Интернете. Googling любой технологии плюс singleton должен поставить вас на правильный путь.

Ответ 3

Чтобы добавить к ответу Кевина, ваш конструктор для вашего ресурса класса действительно должен быть закрытым для того, чтобы он был истинным синглом, иначе ничто не мешает кому-то создать новый экземпляр класса Resources через конструктор. Это не решает вашу проблему, но это не мешает использовать синглтон.

Ответ 4

Просто вызов свойства singleton в другой сборке из двух разных процессов создаст разные экземпляры этого класса.

Но вы можете легко обмениваться информацией между процессами, используя .Net Remoting или события межпроцессного пожара, если вам нужна простая сигнализация (EventWaitHandle).

[Изменить:] Чтобы сделать его похожим на Singleton на вызывающих абонентов, вы можете открыть класс, который будет внутренне использовать Remoting для создания экземпляра синглета, а затем прозрачно вернуть экземпляр. Вот пример, который (я думаю) делает это: http://www.codeproject.com/KB/dotnet/remotingsingleton.aspx

Ответ 5

Есть способы сделать это, как указано выше. Но это неудобно, если вы используете WCF или удаляете. Пожалуйста, попробуйте методы синхронизации потоков interprocess.

Для получения дополнительной информации прочитайте онлайн-бесплатную электронную книгу по потоку

http://www.albahari.com/threading/

Специально см. конструкции синхронизации кросс-процесса здесь...

http://www.albahari.com/threading/part2.aspx#_Synchronization_Essentials