- •Тверской государственный технический университет
- •Построение Windows сервиса.
- •1. Теоретическая часть.
- •1.1. Альтернативные хосты для удаленных объектов
- •1.2. Хостинг удаленных объектов с использованием службы Windows
- •1.3. Построение сборки удаленных объектов.
- •1.4. Разработка Windows службы
- •1.4.1. Реализация метода Main() в классе Program.
- •1.4.2. Реализация класса Windows-службы CarService.
- •1.4.2.1. Метод CarService.OnStart()
- •1.4.2.2. Метод OnStop()
- •1.4.3. Создание инсталлятора службы
- •1.6. Инсталляция службы CarService
- •1.5. Создание консольного приложения клиента.
- •1.6. Создание Windows приложения клиента
- •1.7. Хостинг удаленных объектов с использованием iis
- •2. Указания к выполнению лабораторной работы
- •2.1. Задание на лабораторную работу
- •2.2. Содержание отчета по лабораторной работе
- •Литература:
1.6. Создание Windows приложения клиента
В данном примере используется уже имеющаяся сборка библиотеки класса CarProvider и Windows-служба CarService, созданные для консольного приложения. Таким образом, все необходимые изменения касаются только модификации приложения клиента. Основной особенностью данного примера Windows приложения клиента заключается не только в изменении его внешнего вида, но и в иллюстрации возможности использования делегата при обращении к одному из методов удаленного объекта. Вот его программный код:
using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
//using System.Runtime.Remoting.Channels.Http;
using System.Runtime.Remoting.Channels.Tcp;
using CarGeneralAsm;
using System.Collections.Generic;
namespace AsyncWKOCarProviderClient
{
public partial class Form2 : Form
{
// Обявление типа делегата, задающего сигнатуру функций, с которыми он будет
// работать
internal delegate List<JamesBondCar> GetAllAutosDelegate();
GetAllAutosDelegate CarDelegate = null; // Переменная типа делегата (сам делегат)
// Ссылка на список автомобилей для их отображения на форме приложения клиента
List<JamesBondCar> allJBCs=null;
CarProvider cp = null; // Ссылка на удаленный объект (прокси)
public Form2()
{
InitializeComponent();
//Создание прокси удаленного поставщика
object remoteObj = Activator.GetObject(typeof(CarGeneralAsm.CarProvider),
"tcp://localhost:32469/CarProvider.rem");
cp = (CarProvider)remoteObj; // Инициализация ссылки на удаленный объект (прокси)
//Создание объекта делегата (иницииализация ссылки на объект делегата)
CarDelegate = new GetAllAutosDelegate(cp.GetAllAutos);
}
//Метод для вызова делегата
void CallDelegate()
{
//Асинхронный вызов делегата
IAsyncResult ar = CarDelegate.BeginInvoke(null, null);
if (ar == null)
{
MessageBox.Show("Делегат не хочет вызываться!!!");
return;
}
MessageBox.Show("Удаленный объект заполняет список.");
//Работа делегата (то есть работа метода, включенного в делегат)
while (!ar.IsCompleted) { } // Пока делегат не закончит свою работу, ждем…
allJBCs = CarDelegate.EndInvoke(ar);//Делегат возвращает список автомобилей
string str = "Удаленный объект заполнил весь список! Всего: ";
str += allJBCs.Count.ToString();
str += " Машин";
MessageBox.Show(str);// Отображаем строку str в виде окна с сообщением
}
// Обработчик события при нажатии на клавишу "Добавить автомобиль…"
private void AddCarButton_Click(object sender, EventArgs e)
{
if (cp == null) // если нет ссылки на удаленный объект, то (защита от "дурака")
{
// Получаем ссылку на удаленный объект (его прокси)
object remoteObj = Activator.GetObject(typeof(CarGeneralAsm.CarProvider),
"tcp://localhost:32469/CarProvider.rem");
cp = (CarProvider)remoteObj;
}
if (cp == null) return; //Если ссылки – нет, то выходим из функции
// Добавляем новый автомобиль в список их поставщика на удаленном объекте
cp.AddNewJBCar(NameTextBox.Text, int.Parse(SpeedTextBox.Text),
FlyCheckBox.Checked, SweemCheckBox.Checked);
}
// Обработчик события при нажатии на клавишу "Заполнить список на форме клиента"
private void FillListButton_Click(object sender, EventArgs e)
{
CallDelegate();// Вызов делегата (содержащего соотв. метод удаленного объекта)
List<string> carNames = new List<string>();// Вспомогательный список строк
string str = ""; // Служебная (локальная) переменная типа строки
foreach (JamesBondCar car in allJBCs)// Формирование вспомогательного списка строк
{
str = car.PetName;
str += " Макс.скорость = ";
str += (car.MaxSpeed.ToString()+"; ");
if (car.CanFly) str += "Может летать! ";
else str += "Не может летать. ";
if (car.CanSubmerge) str += "Может плавать!";
else str += "Не может плавать.";
carNames.Add(str);
}
//Связывание вспомогательного списка с содержимым компоненты списка
listBox1.DataSource = carNames;
}
}
}
После компиляции и запуске приложения клиента и включенной службе CarService для хостинга (владения) удаленных объектов типа CarProvider получим приложение способное взаимодействовать с зарегистрированным удаленным объектом. Его внешний вид показан на рис.7.
Рис.7. Внешний вид запущенного Windows приложения клиента.