从另一个线程调用要在主线程中运行的函数.请帮忙 [英] Invoking a function to run in main thread, from another thread. Help Please

查看:82
本文介绍了从另一个线程调用要在主线程中运行的函数.请帮忙的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

你好大师!

我正在编写一个简单的Windows窗体媒体播放器程序,该程序由一个充当播放列表的ListView和一个播放文件的DirectShow组成.到目前为止,一切正常,我从ListView中选择要播放的文件,然后单击播放"并运行.我可以停下来 播放另一个文件,一切正常.

I am writing a simple windows forms media player program, consisting of a ListView which acts as a playlist, and DirectShow which plays the files. It all works fine so far, i select the file from the ListView to play, hit play and it runs. I can stop and play another file so that is all working good.

但是现在我正在实现连续播放,因此当一个文件结束时,程序将继续播放ListView列表中的下一个文件.

Now however i am implementing continuous play, so when one file finishes, the program will continue to play the next file in the ListView list. 

我有一个play(string fName)函数,可以在给定文件名的情况下播放文件.该函数挂接一个自定义事件并创建一个新的事件等待线程,当接收到EventCode.Compelte时,该线程将触发该自定义事件.

I have a play(string fName) function which plays the file, given the file name. This function hooks a custom event and creates a new event waiting thread which, when a EventCode.Compelte is recieved, triggers the custom event.

播放器中的事件挂钩代码(字符串fName):

Event hooking code in player(string fName):

 

myPlayer.StopPlay += new player.PlayerEvent(finishedPlaying);

 

因此,当触发此事件时,将调用finishPlaying函数.此功能检查是继续播放下一个文件还是只是停止播放.

So when this event is triggered, the finishedPlaying function is called. This function checks whether to continue playing the next file, or to just stop.

在我要继续播放下一个文件的情况下,我想使用新文件名调用play()函数.但是,由于我相信finishPlaying函数正在事件等待线程中运行,因此我需要以某种方式调用此play() 在主线程中,从事件等待线程开始.

In the case where i want to continue playing the next file, i would like to call the play() function with the new filename. However as I believe that the finishedPlaying function is running in the event waiting thread, i need to somehow invoke this play() function in the main thread, from the event waiting thread.

下面是我尝试使用的代码,但是当调用mainDispatcher.Invoke时,它只是锁定了主线程,我无法按下任何按钮或任何东西.

Below is the code that i have attempted to use, however when mainDispatcher.Invoke is called, it just locks up the main thread and i am unable to press any buttons or anything.

 

        Dispatcher mainDispatcher;
        // Delegate to be used by dispatcher to call the play function within the main thread, from another thread
        delegate void playCallBack(string fName);

	public frmMain()
        {
            InitializeComponent();
            InitializeModes();
            mainDispatcher = Dispatcher.CurrentDispatcher;
        }

        private void finishedPlaying(Object sender)
        {
            // If we are in continuous mode and this is not the last track, play the next one
            if (mode.continuous && (mode.currentIndex < lvdNdPlayList.Items.Count -1) )
            {
                ListViewItem lvItem = getFileNameSafe(++mode.currentIndex);
                string fName = lvItem.SubItems[1].Text + "\\" + lvItem.SubItems[0].Text;
                // Set the new state to stopped, as the file has finished playing
                state = playerState.Stopped;
                // Instantiate the delegate to call play() in main thread from this thread
                playCallBack playSafe = play;
                // Now use the dispatcher to call the delegate safely form main thread
                mainDispatcher.Invoke(playSafe, fName);
                //play(fName);
            }
            else
            {
                // irrelevant working code
            }
        }


这有点超出我的能力,因为我只是在学习使用多线程.任何帮助将不胜感激.


This is a little above my head as i am just learning to use multithreading. Any help would be greatly appreciated.

 

谢谢

克里斯

 

 

 

推荐答案

首先,您确定您的plan函数在单独的线程而不是GUI线程中运行吗?

First of all,  are you sure your plan function is running in a separate thread instead of GUI thread?

在winform应用程序上,这就是我要做的事情.

On a winform application , here is what I will do.

在其内部初始化一个新的线程以运行Dotask函数,而DDD函数将在GUI线程上执行.

I initialise a new thread to run the Dotask function, inside of it , while the DDD function will be executed on GUI thread. 

        public 委托 void doIt ();

       public delegate void doIt();

 

        私有 无效 button1_Click ( 对象 sender EventArgs e )

        private void button1_Click(object sender, EventArgs e)

        {

        {

            ThreadPool . QueueUserWorkItem ( new WaitCallback ( this . Dotask ));

            ThreadPool.QueueUserWorkItem(new WaitCallback(this.Dotask));

        }

        }

 

        private void Dotask ( object state )

        private void Dotask(object state)

        {

        {

            如果 ( . button1 . InvokeRequired )

            if(this.button1.InvokeRequired)

            {

            {

                . button1 . 调用( doIt ( this . DDD ));

                this.button1.Invoke(new doIt(this.DDD));

            }

            }

        }

        }

        私有 无效 DDD ()

        private void DDD()

        {

        {

            . button1 . 已启用 = false ;

            this.button1.Enabled = false;

        }

        }


这篇关于从另一个线程调用要在主线程中运行的函数.请帮忙的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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