What's new
  • Visit Rebornbuddy
  • Visit Resources
  • Visit API Documentation
  • Visit Downloads
  • Visit Portal
  • Visit Panda Profiles
  • Visit LLamamMagic

Помогите! WPF-WinForms-Threads

sholimi

New Member
Joined
Oct 25, 2014
Messages
70
Reaction score
0
Всем доброго времени суток!
Я не C-шарпер, потому прошу не сильно ругать.
Предыстория:
Имелся скрипт с некоторым пвп-функционалом (это не суть), после старта скрипта отрывалась форма (WinForms), которая онлайн отображала некоторую информацию (дистанцию до цели и т.п.)
Вот так открывалась форма
Code:
form = new FormDist(this);
            formThread = new Thread(RunForm);
            formThread.Start();
public void RunForm()
        {
            try
            {
                Application.Run(form);
            }
            catch (System.ComponentModel.Win32Exception) { }
            catch (Exception error)
            {
                Log("error (" + error.GetType() + ") on form: " + error.Message);
            }
        }
Конструктор формы
Code:
public FormDist(Core core)
        {
            InitializeComponent();
            this.FormClosing += OnFormClosing;
            this.core = core;

            thread = new Thread(UpdateDist);
            thread.Start();        
        }
Прямо в конструкторе страртует поток, который выполняет некие действия (бесконечный цикл), на обработчике закрытия формы висит код, который прибивает поток, как только форма закрывается.
В скрипте в методе PluginStop прописан был код, что прибивал окно и поток, к котором оно запущено при остановке скрипта.
Все хорошо работало пока мне не захотелось сделать это окно прозрачным и решено было сделать его на WPF.
Было много проблем при перестроении, одной из который было то, что без BeginInvoke нельзя было менять состояния контролов на форме (ругалось на то, что объект принадлежит другому потоку), но одну проблему не смог так и решить.
Форма открывается так (Пример брал на форуме у Out'а)
Code:
private void RunFormWpf()
        {
            try
            {
                mainForm = new FormInfoWPF(this);
                mainForm.Show();
                System.Windows.Threading.Dispatcher.Run();

            }
            catch (Exception error)
            {
                Console.WriteLine(error.ToString());
            }
        }
Code:
 formThread = new Thread(RunFormWpf);
            formThread.SetApartmentState(ApartmentState.STA);
            formThread.Start();
В конструкторе формы так же создается сразу новый поток для обработки контролов формы (вывода данных в них), как и в случае с WinForms
НО ! При закрытии скрипта (вручную или программно) он не выгружается до конца (почти все методы прекращают работать, работают в основном только event'ы), хотя в списке лаунчера, он значится как выгруженный, но dll его блочится, перезаписать ее нельзя.
Вот так я прибиваю форму и ее поток (так же взято на форуме с примера Out'а)
Code:
try
            {
                if (mainForm != null)
                {
                    mainForm.Dispatcher.Invoke(new Action(() => mainForm.Close()));
                }
            }
            catch (Exception exception)
            {
                Log("Лажа при закрытии окна");
            }
            Log("ok2");
            try
            {
                formThread.Abort();
                formThread.Join();
            }
            catch (Exception error)
            {
                Log("Лажа при закрытии потока");
            }
Опытным путем удалось установить, что не останавливается поток формы. Из-за этого скрипт не выгружается полностью. Что я делаю не так ? Может нельзя ему в конструктор как параметр передавать Core ? 2 дня не могу разобраться, а прозрачное окошко хочется получить ) Помогите, пожалуйста.
Приношу извинения ENG-комmюнити за отсутствие перевода, я не владею английским и гугл-транслейт вряд ли все это нормально переведет.
 
После многих дней поисков таки удалось решить (отчасти) проблему, в метод, где создается новый экземпляр формы WPF добавляю эту подписку
formWpf.Closed += (sender2, e2) =>
{
if (formWpf != null) formWpf.Dispatcher.InvokeShutdown();
};
Тему можно закрыть, спасибо.
 
Back
Top