从另一个线程调用要在主线程中运行的函数.请帮忙 [英] Invoking a function to run in main thread, from another thread. Help Please
问题描述
你好大师!
我正在编写一个简单的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屋!