在不同线程中调用WPF窗口并与主线程进行通信-如何? [英] Calling WPF window in different thread and communicating from main thread - How?

查看:63
本文介绍了在不同线程中调用WPF窗口并与主线程进行通信-如何?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是C#的新手,也许我的问题太简单了,但是我花了一些时间尝试解决这个有人会说些微不足道的问题.

I am new in C# and maybe my question is too easy, but I've spent some time trying to solve this someone would say trivial problem.

让我们开始吧:

问题::我正在从主线程运行一些长时间运行的进程(应该是这样),并希望在新的状态窗口中显示进度.自然,该状态窗口应在单独的线程中运行.问题是要获得新的窗口引用 在主线程中,所以我可以调用Delegate来将文本添加到状态中.

Problem: I am running some long running process from main thread (it should be like this) and want to display progress in new status window. Naturally that status window should run in separate thread. The problem is to get new window refference in main thread, so I could call Delegate which adds text to status.

我的代码:

在主线程中,我有一个用以下实例化的类:

In Main thread I have class which is instantiated with following:

 

        private ManualResetEvent m_StatusDialogCreated;
        private ShareIt.StatusWindow m_StatusDialog;
        private System.Threading.Thread m_StatusDialogThread;

From called Method I execute:

public bool updateData(string rapidContext)
        {
            try
            {
                OpenStatusDialog();
 
                msgSend("Updating Database...");

...

 

Also I have defined methods:

 

        private void StatusDialogThread()
        {
            Application.Current.Run(this.m_StatusDialog = new
            ShareIt.StatusWindow(this.m_StatusDialogCreated));
        }
 
        public void OpenStatusDialog()
        {
            this.m_StatusDialogCreated = new ManualResetEvent(false);
            this.m_StatusDialogThread = new Thread(new ThreadStart(StatusDialogThread));
            this.m_StatusDialogThread.SetApartmentState(ApartmentState.STA);
            this.m_StatusDialogThread.Start();
            // wait for the dialog to be ready
            WaitHandle.WaitAll(new ManualResetEvent[] { this.m_StatusDialogCreated });
        }
 
        public void msgSend(string message)
        {
            if (this.m_StatusDialog!= null)
                this.m_StatusDialog.Dispatcher.BeginInvoke(this.m_StatusDialog.m_SetStatusMessage, new Object[]{message});
        }
 
        public void CloseStatusDialog()
        {
            if (this.m_StatusDialog != null)
                this.m_StatusDialog.Dispatcher.BeginInvoke(this.m_StatusDialog.m_CloseDialog, null);
            else // failsafe, dont want some half dead threads hanging around - will work on this ;)
                if (this.m_StatusDialogThread.ThreadState != System.Threading.ThreadState.Stopped)
                    this.m_StatusDialogThread.Abort();
        }

My form is WPF form with code:

 

    // declaration of delegates
    public delegate void SetStatusMessageDelegate(string message);
    public delegate void CloseDialogDelegate();
 
    public partial class StatusWindow : Window
    {
 
        public StatusWindow()
        {
            InitializeComponent();
        }
 
        public void add(string newText)
        {
            textboxContent.Text = textboxContent.Text + "\n" + newText;
            textboxContent.ScrollToEnd();
            Debug.WriteLine(newText);
        }
 
 
        public SetStatusMessageDelegate m_SetStatusMessage;
        public CloseDialogDelegate m_CloseDialog;
        private System.Threading.ManualResetEvent m_Ready;
 
        public StatusWindow(System.Threading.ManualResetEvent dialogCreated)
        {
            this.m_SetStatusMessage = new SetStatusMessageDelegate(SetStatusMessage);
            this.m_CloseDialog = new CloseDialogDelegate(CloseDialog);
            this.m_Ready = dialogCreated;
        }
 
        // signal that methods of the dialog can now be invoked
        protected override void OnActivated(EventArgs e)
        {
            this.m_Ready.Set();
            base.OnActivated(e);
        }
 
        private void SetStatusMessage(string message)
        {
            this.add(message);
        }
 
        private void CloseDialog()
        {
            this.Close();
        }

When I start I get exception in line:

 

Application.Current.Run(this.m_StatusDialog = new
            ShareIt.StatusWindow(this.m_StatusDialogCreated));

The problem is that I can't access m_StatusDialog from the new thread. 

I've tried many things, but it seems I don't see obvious.

On the net I've found dosens examples of how to update WPF running in main thread if we start worker thread, but for my case nothing.

Thanks a lot

All the best

Goran

Could you, please, help me with that.

推荐答案

我对这一切都不了解,无法确切地回答问题所在,但是这种方法似乎非常落后.您是否真的需要长时间运行的流程才能在UI线程上执行,并且UI(状态窗口)要在新的单独线程上运行?它会 如果您在新线程上运行流程并将其传回主UI线程以显示状态,则变得容易得多.
I don't know enough about all this to answer exactly what the problem is, but the approach seems very backwards. Do you really need your long running process to execute on the UI thread and your UI (status window) to run on a new separate thread? It would be a lot easier if you run your process on a new thread and have it communicate back to main UI thread to display the status.


这篇关于在不同线程中调用WPF窗口并与主线程进行通信-如何?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆