Intereting Posts
Как может быть проверен единичный тест на исключение? Почему максимальное значение Int32 равно 0x7FFFFFFF? Автоматизация Visual Studio с EnvDTE Как я могу подписаться на цифровой подписью? Random DateTime между диапазоном – не унифицированный вывод Могу ли я продлить Button, чтобы добавить событие RightClick таким образом, чтобы также поддерживались графические побочные эффекты? Как генерируется случайное число во время выполнения? Как вернуть 401 вместо 302 в ASP.NET Core? C #: создать пользовательское предупреждение в Visual Studio, если определенный метод используется в исходном коде DLL отсутствует в списке модhive в VS2010 Сравнить объекты? Показать выпадающий список календаря с производным classом DateTimePicker Цитирование через DataTable Разница между переменной-членом и элементом-членом? Отображать всплывающее подтверждающее сообщение с MVC C # после обратной передачи

Разделение объектов между приложениями?

Предположим, у меня есть большой массив данных, обновленный 1000+ раз в секунду.
Другое приложение хочет получить доступ и прочитать массив за короткий промежуток времени. Оба приложения находятся на одной машине.

Я попытался использовать WCF для межпроцессного взаимодействия, но сериализация и отправка всего массива (или большого объекта) тысячи раз в секунду является неосуществимой эффективностью.
Есть ли способ прямого доступа к объектам из разных приложений в c #?

    Существует несколько технологий IPC, которые вы можете использовать, хотя до сегодняшнего дня WCF по-прежнему актуальны.

    трубы

    Трубы – одна из таких технологий. Он двоичный, работает в режиме ядра и очень быстро! Хотя он довольно низкоуровневый и не дает доступа к «объектам».

    .NET Remoting

    .NET Remoting предоставит доступ к объектам, но, возможно, не так быстро, как трубы.

    Оба канала и удаленное соединение .NET быстрее, чем сериализационные технологии WCF, которые преобразуют вещи в многословный XML / SOAP.

    COM

    COM – это двоичный протокол для IPC. COM – модель клиентского сервера, где клиент запрашивает данные с сервера COM или OLE. Красота COM – это то, что у вас есть прямой доступ к объектам на сервере – они не сериализованы. Например, запрос элемента в SAFEARRAY .

    SAFEARRAY – это безопасная для автоматизации структура произвольных измерений, состоящая из безопасных по типу данных. К счастью, .NET скроет SAFEARRAY gobble-de-gook для нас.

    В моем примере я создал class Manager который будет выставлять массив. Чтобы добраться до Manager я использовал шаблон фабрики, так что Manager по существу является одноэлементным.

    Вы должны выложить свой проект следующим образом:

    • MyComLib.Contracts.dll – содержит все интерфейсы
    • MyComLib.dll – содержит реализацию Factory , Manager

    Сначала контракты:

     [ComVisible(true)] [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)] public interface IArrayItem { #region Properties string Name { get; set; } int Whatsit { get; set; } #endregion } [ComVisible(true)] [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)] public interface IFactory { #region Methods IManager CreateManager(); #endregion } [ComVisible(true)] [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)] public interface IManager { #region Properties IArrayItem[] Array { get; } #endregion } public static class MyComLibConstants { public const string FactoryProgId = "MickyD.MyComLib.Factory.1"; } 

    Теперь для заводской схемы:

     [ComVisible(true)] [ClassInterface(ClassInterfaceType.None)] [ComDefaultInterface(typeof (IFactory))] [Guid("...")] [ProgId(MyComLibConstants.FactoryProgId)] public class Factory : MarshalByRefObject, IFactory { #region IFactory Members ///  /// Creates the manager. ///  ///  public IManager CreateManager() { return Manager.Instance; } #endregion } 

    Менеджер:

     [ComVisible(true)] [ClassInterface(ClassInterfaceType.None)] [ComDefaultInterface(typeof (IManager))] [Guid("...")] internal sealed class Manager : MarshalByRefObject, IManager { private static Manager _instance; #region Constructor ///  /// Prevents a default instance of the  class from being created. ///  private Manager() { const int n = 5000; Array = new IArrayItem[n]; for (int i = 0; i < n; i++) { Array[i]=new ArrayItem(); } } #endregion #region Properties ///  /// Gets the instance. ///  ///  /// The instance. ///  public static IManager Instance { get { if (_instance == null) { _instance = new Manager(); } return _instance; } } #endregion #region IManager Members ///  /// Gets the array. ///  ///  /// The array. ///  public IArrayItem[] Array { get; private set; } #endregion } 

    Тестовое приложение. Это должно ссылаться только на MyComLib.Contracts.dll, а не на MyComLib.dll .

     class Program { static void Main(string[] args) { var type = Type.GetTypeFromProgID(MyComLibConstants.FactoryProgId); var factory = Activator.CreateInstance(type) as IFactory; var manager = factory.CreateManager(); var x = manager.Array[500].Whasit; } } 

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

    Для этого вам нужно настроить COM-суррогат, который подробно объясняется здесь .

    Сопоставление файлов / общая память

    Наконец, File Mapping позволяет вам манипулировать файлом, как если бы это был не что иное, как большой блок памяти в адресном пространстве процесса. Нет искаженного файла; операции чтения / записи. Просто возьмите указатель на блок памяти и начните чтение / запись. Система сделает все остальное.

    MSDN:

    Вы можете использовать специальный случай сопоставления файлов для предоставления именованной общей памяти между процессами. Если вы укажете файл подкачки системы при создании объекта сопоставления файлов, объект сопоставления файлов рассматривается как блок разделяемой памяти. Другие процессы могут обращаться к одному и тому же блоку памяти, открывая тот же объект сопоставления файлов. Расскажи мне больше

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

    Однако разделяемая память через файл подкачки технически позволяет исключить сериализацию-де-сериализацию между приложениями клиент-сервер и дублирование данных «в куче». Хотя, как я уже сказал, вам может понадобиться настроить приложение для работы с буферами необработанной памяти, а не с объектами.

    Расскажи мне больше

    • Операции с трубами в .NET Framework
    • .NET Remoting
    • Межпроцессные коммуникации

    ПРИМЕЧАНИЕ. Вопреки распространенному мнению, .NET Remoting не является полностью устаревшим . Одним из них является общение между объектами в разных AppDomains в рамках одного процесса, что вы обычно делаете в plug-in systems .