WCF, Получая доступ к элементам управления Windows Forms от сервиса

Память JVM состоит из следующих сегментов:

  1. Память "кучи", которая является устройством хранения данных для объектов Java
  2. Память Не"кучи", которая используется Java для хранения загруженных классов и других метаданных
  3. сам код JVM, JVM внутренние структуры, загруженный код агента профилировщика и данные, и т.д.

, JVM имеет "кучу", которая является областью данных во время выполнения, от которой выделяется память для всех экземпляров класса и массивов. Это создается при запуске JVM.

размер "кучи" может быть настроен со следующими опциями VM:

-Xmx<size> - to set the maximum Java heap size
-Xms<size> - to set the initial Java heap size

По умолчанию, максимальный размер "кучи" составляет 64 МБ.

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

следующая команда запускает JVM с 256 МБ памяти и позволяет процессу Java использовать до 4G (4096 МБ) памяти.

java -Xms256m -Xmx4g
5
задан Matt Davis 2 September 2009 в 14:02
поделиться

4 ответа

Прежде всего, в интерфейсе должен быть атрибут ServiceContract, а не метод PrintMessage ().

Используя исправленную версию вашего примера, вы можете сделать это следующим образом.

[ServiceContract]
public interface IService
{
    [OperationContract]
    string PrintMessage(string message);
}
public class Service : IService
{
    public string PrintMessage(string message)
    {
        // Invoke the delegate here.
        try {
            UpdateTextDelegate handler = TextUpdater;
            if (handler != null)
            {
                handler(this, new UpdateTextEventArgs(message));
            }
        } catch {
        }
    }
    public static UpdateTextDelegate TextUpdater { get; set; }
}

public delegate void UpdateTextDelegate(object sender, UpdateTextEventArgs e);

public class UpdateTextEventArgs
{
    public string Text { get; set; }
    public UpdateTextEventArgs(string text)
    {
        Text = text;
    }
}

public class MainForm : Form
{
    public MainForm()
    {
        InitializeComponent();

        // Update the delegate of your service here.
        Service.TextUpdater = ShowMessageBox;

        // Create your WCF service here
        ServiceHost myService = new ServiceHost(typeof(IService), uri);
    }
    // The ShowMessageBox() method has to match the signature of
    // the UpdateTextDelegate delegate.
    public void ShowMessageBox(object sender, UpdateTextEventArgs e)
    {
        // Use Invoke() to make sure the UI interaction happens
        // on the UI thread...just in case this delegate is
        // invoked on another thread.
        Invoke((MethodInvoker) delegate {
            MessageBox.Show(e.Text);
        } );
    }
}

По сути, это решение, предложенное @Simon Fox, т.е. использование делегата. Будем надеяться, что это просто добавит немного плоти к костям, так сказать.

5
ответ дан 14 December 2019 в 01:12
поделиться

Лучший способ справиться с таким сценарием - внедрить форму в службу в качестве зависимости. Я бы определил какой-то интерфейс, который отделяет код формы от кода WCF:

public interface IFormService
{
    string Text { get; set; }
}

Вы можете сделать так, чтобы ваша форма реализовала интерфейс IFormService, установив реальное свойство, которое вы хотите обновить.

Для вашей службы потребуется экземпляр IFormService для выполнения своей работы:

public class Service : IService
{
    private readonly IFormService form;

    public Service(IFormService form)
    {
        this.form = form
    }

    public string PrintMessage(string message)
    {
        this.form.Text = message;
    }
}

Поскольку класс Service теперь не имеет конструктора по умолчанию, вам также потребуется реализовать настраиваемый ServiceHostFactory, который может создавать экземпляры класса Service и внедрять конкретную реализацию IFormService.

3
ответ дан 14 December 2019 в 01:12
поделиться

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

У вас будут проблемы при попытке обновления текстовое поле, потому что делегат будет вызываться в потоке, отличном от того, в котором текстовое поле было создано. В мире WPF вы бы использовали Dispatcher.BeginInvoke, чтобы обойти это, не зная, что такое эквивалент WinForms.

1
ответ дан 14 December 2019 в 01:12
поделиться

Службе потребуется ссылка на экземпляр формы, а не только на тип формы.

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

Простым подходом было бы следующее:

  1. Добавьте конструктор к вашему классу обслуживания, который принимает ссылку на ваш экземпляр формы. Если вы размещаете свою службу внутри формы, это должно быть легко.
  2. Добавьте общедоступные свойства для свойств элемента управления, которые вы хотите установить из службы. Свойства должны быть общедоступными или внутренними и будут устанавливать значения свойств элементов управления.
  3. В вашем сервисе вы устанавливаете значения вновь добавленных свойств.
0
ответ дан 14 December 2019 в 01:12
поделиться
Другие вопросы по тегам:

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