Может ли одноэлементный класс внутри DLL быть общим для процессов?

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

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

  • Я должен подчеркнуть, что я не буду контролировать клиентское приложение. Решение должно содержаться внутри самой структуры (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, чтобы закрыть процесс!

Вывод:

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

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


person Bobby Cannon    schedule 24.06.2009    source источник
comment
Я должен подчеркнуть, что я не буду контролировать клиентское приложение. Решение должно содержаться внутри самой структуры (DLL).   -  person Bobby Cannon    schedule 24.06.2009


Ответы (5)


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

person kemiller2002    schedule 24.06.2009
comment
У меня был тот же вопрос, но в качестве альтернативы, могу ли я поместить этот одноэлементный экземпляр в GAC, и оба процесса могут ссылаться на этот экземпляр? Таким образом, если я обновлю объект из одного процесса, не получит ли другой процесс обновленный экземпляр? ИЛИ каждый процесс загружает экземпляр в свой собственный процесс? - person hangar18; 13.02.2012
comment
@hangar18, это точно такой же вопрос - размещение его в GAC ничего особенного не делает, это все еще dll! - person markmnl; 25.10.2013

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

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

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

person JaredPar    schedule 24.06.2009

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

person AlbertoPL    schedule 24.06.2009
comment
Вы правы в том, что конструктор должен быть закрытым. Я исправил образец. - person Bobby Cannon; 24.06.2009
comment
Это только пример. Я не пытаюсь поделиться датой. Я пытаюсь контролировать аппаратный ресурс. - person Bobby Cannon; 24.06.2009

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

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

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

person Groo    schedule 24.06.2009

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

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

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

В частности, смотрите конструкции синхронизации между процессами здесь...

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

person Shafqat Ahmed    schedule 24.06.2009