Сообщение Re[5]: Как вызвать метод формы из родительского потока? от 18.09.2014 12:24
Изменено 18.09.2014 12:38 fortnum
Здравствуйте, mDmitriy, Вы писали:
D>Поток с формой запускается при активизации COM+ объекта и отображает иконку в трее.
D>При удалении COM+ объекта надо бы форму высвободить — по идее, это должно привести к закрытию потока (ибо Application.Run).
D>С чем, собственно, и был связан мой первоначальный вопрос.
А почему ты хочешь управлять формой из компонента? На мой взгляд — это не самое лучшее решение в плане архитектуры. Наверняка, ты еще из этой формы своим компонентом управляешь, или периодически мониторишь его состояние. Короче, у тебя, подозреваю, сейчас двунаправленная логическая связь "компонент"<->"форма". Гораздо лучше сделать так, чтобы либо компонент ничего не знал о форме, либо форма ничего не знала о компоненте. Т.к. в форме, не знающей ничего о компоненте, смысла нет, то получается, надо сделать так: "компонент"<-"форма". Т.е. компонент ничего не знает о форме, а форма знает о компоненте. Более того, форма для компонента, по сути, — тот же клиент. Поэтому я бы предложил решить вопрос ближе к такому варианту:
D>Поток с формой запускается при активизации COM+ объекта и отображает иконку в трее.
D>При удалении COM+ объекта надо бы форму высвободить — по идее, это должно привести к закрытию потока (ибо Application.Run).
D>С чем, собственно, и был связан мой первоначальный вопрос.
А почему ты хочешь управлять формой из компонента? На мой взгляд — это не самое лучшее решение в плане архитектуры. Наверняка, ты еще из этой формы своим компонентом управляешь, или периодически мониторишь его состояние. Короче, у тебя, подозреваю, сейчас двунаправленная логическая связь "компонент"<->"форма". Гораздо лучше сделать так, чтобы либо компонент ничего не знал о форме, либо форма ничего не знала о компоненте. Т.к. в форме, не знающей ничего о компоненте, смысла нет, то получается, надо сделать так: "компонент"<-"форма". Т.е. компонент ничего не знает о форме, а форма знает о компоненте. Более того, форма для компонента, по сути, — тот же клиент. Поэтому я бы предложил решить вопрос ближе к такому варианту:
using System;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
static class Program
{
static void Main()
{
Console.WriteLine("Клиент: нажми любую клавишу, чтобы подключиться к серверу."); Console.ReadKey(true);
var threadUIClass1 = Task.Run(() => new ThreadUIClass1()).Result;
Console.WriteLine("Клиент: нажми любую клавишу, чтобы отключиться от сервера."); Console.ReadKey(true);
Task.Run(() => threadUIClass1.Dispose());
Console.WriteLine("Press any key to exit.");
Console.ReadKey(true);
}
public class ThreadUIClass1 : IDisposable
{
volatile int _data;
volatile bool _disposed;
public ThreadUIClass1()
{
new Thread(() =>
{
while (!_disposed)
{
Task.Delay(100).Wait();
_data = new Random().Next(int.MinValue, int.MaxValue);
}
Console.WriteLine("Сервер: рабочий поток завершен.");
}).Start();
Console.WriteLine("Сервер: рабочий поток запущен.");
new Thread(() =>
{
var form = new Form();
var timer = new System.Windows.Forms.Timer() { Interval = 5000 };
timer.Tick += (o, e) =>
{
form.Text = _data.ToString();
if (_disposed)
{
form.Dispose();
}
};
timer.Start();
Console.WriteLine("Сервер: локальный пользовательский интерфейс запущен.");
Application.Run(form);
Console.WriteLine("Сервер: локальный пользовательский интерфейс остановлен.");
}).Start();
}
public void Dispose()
{
_disposed = true;
Console.WriteLine("Сервер: удаленный клиент отсоединен.");
}
}
}
}
Re[5]: Как вызвать метод формы из родительского потока?
Здравствуйте, mDmitriy, Вы писали:
D>Поток с формой запускается при активизации COM+ объекта и отображает иконку в трее.
D>При удалении COM+ объекта надо бы форму высвободить — по идее, это должно привести к закрытию потока (ибо Application.Run).
D>С чем, собственно, и был связан мой первоначальный вопрос.
А почему ты хочешь управлять формой из компонента? На мой взгляд — это не самое лучшее решение в плане архитектуры. Наверняка, ты еще из этой формы своим компонентом управляешь, или периодически мониторишь его состояние. Короче, у тебя, подозреваю, сейчас двунаправленная логическая связь "компонент"<->"форма". Гораздо лучше сделать так, чтобы либо компонент ничего не знал о форме, либо форма ничего не знала о компоненте. Т.к. в форме, не знающей ничего о компоненте, смысла нет, то получается, надо сделать так: "компонент"<-"форма". Т.е. компонент ничего не знает о форме, а форма знает о компоненте. Более того, форма для компонента, по сути, — тот же клиент. Поэтому я бы предложил решить вопрос ближе к такому варианту:
D>Поток с формой запускается при активизации COM+ объекта и отображает иконку в трее.
D>При удалении COM+ объекта надо бы форму высвободить — по идее, это должно привести к закрытию потока (ибо Application.Run).
D>С чем, собственно, и был связан мой первоначальный вопрос.
А почему ты хочешь управлять формой из компонента? На мой взгляд — это не самое лучшее решение в плане архитектуры. Наверняка, ты еще из этой формы своим компонентом управляешь, или периодически мониторишь его состояние. Короче, у тебя, подозреваю, сейчас двунаправленная логическая связь "компонент"<->"форма". Гораздо лучше сделать так, чтобы либо компонент ничего не знал о форме, либо форма ничего не знала о компоненте. Т.к. в форме, не знающей ничего о компоненте, смысла нет, то получается, надо сделать так: "компонент"<-"форма". Т.е. компонент ничего не знает о форме, а форма знает о компоненте. Более того, форма для компонента, по сути, — тот же клиент. Поэтому я бы предложил решить вопрос ближе к такому варианту:
using System;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
static class Program
{
static void Main()
{
Console.WriteLine("Клиент: нажми любую клавишу, чтобы подключиться к серверу."); Console.ReadKey(true);
var threadUIClass1 = Task.Run(() => new ThreadUIClass1()).Result;
Console.WriteLine("Клиент: нажми любую клавишу, чтобы отключиться от сервера."); Console.ReadKey(true);
Task.Run(() => threadUIClass1.Dispose());
Console.WriteLine("Press any key to exit.");
Console.ReadKey(true);
}
public class ThreadUIClass1 : IDisposable
{
volatile int _data;
volatile bool _disposed;
public ThreadUIClass1()
{
new Thread(() =>
{
while (!_disposed)
{
Task.Delay(100).Wait();
_data = new Random().Next(int.MinValue, int.MaxValue);
}
Console.WriteLine("Сервер: рабочий поток завершен.");
}).Start();
Console.WriteLine("Сервер: рабочий поток запущен.");
new Thread(() =>
{
var form = new Form();
form.Load += (o, e) =>
{
var timer = new System.Windows.Forms.Timer() { Interval = 5000 };
timer.Tick += (t, x) =>
{
form.Text = _data.ToString();
if (_disposed)
{
form.Dispose();
}
};
timer.Start();
};
Console.WriteLine("Сервер: локальный пользовательский интерфейс запущен.");
Application.Run(form);
Console.WriteLine("Сервер: локальный пользовательский интерфейс остановлен.");
}).Start();
}
public void Dispose()
{
_disposed = true;
Console.WriteLine("Сервер: удаленный клиент отсоединен.");
}
}
}
}