求教跨线程控制MCI播放音乐的问题

时间:2021-07-10 10:57:27
请问为何新开的线程里无法控制主线程实例化的mciPlayer呢,求高人指点,谢谢!

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace threadingPlay
{
public partial class Form1 : Form
{
public clsMCI mciPlayer = new clsMCI();
public System.Windows.Forms.Timer winTimer = new System.Windows.Forms.Timer();


public Form1()
{
InitializeComponent();
winTimer.Tick += this.eventPlay;
winTimer.Interval = 500;
}

private void eventPlay(object sender, EventArgs e)
{
this.winTimer.Stop();
this.mciPlayer.Play("connect.mp3");
}

private void button1_Click(object sender, EventArgs e)
{
Action dm = () =>
{
this.winTimer.Start();
MessageBox.Show(System.Threading.Thread.CurrentThread.ManagedThreadId.ToString());
};
dm.BeginInvoke(null, null);

}

private void button2_Click(object sender, EventArgs e)
{
mciPlayer.Stop();
MessageBox.Show(System.Threading.Thread.CurrentThread.ManagedThreadId.ToString());
}


}

/// <summary>
/// clsMci 的摘要说明。
/// </summary>
public class clsMCI
{
public static uint SND_ASYNC = 0x0001;
public static uint SND_FILENAME = 0x00020000;
[DllImport("winmm.dll")]
public static extern uint mciSendString(string lpstrCommand,
string lpstrReturnString, uint uReturnLength, uint hWndCallback);

public void Play(string fileName)
{
mciSendString(@"close temp_alias", null, 0, 0);
mciSendString("open \"" + fileName + "\" alias temp_alias", null, 0, 0);
mciSendString("play temp_alias repeat", null, 0, 0);
}

public void Stop()
{
mciSendString("close all", null, 0, 0);
}
}

}

4 个解决方案

#1


那就让它在主线程执行, 这样:
        public void DoClick(object sender, EventArgs e)
        {
            if (InvokeRequired) // 是否需要远程调用
            {
                Invoke(new Action<object, EventArgs>(DoClick), sender, e); return;
            }
            /// 主线程的代码
        }

#2


你好,我直接使用invoke报错了:
当前上下文中不存在名称“invoke”
你意思是不是使用类似于:textBox1.Invoke()这样执行呢?
我希望的是不和某控件捆绑使用,可能表达的不太正确,新手,谢谢。

#3


我最终的目的是这样的:
在HttpWebRequest异步连接的时候超过n秒钟就播放一个音乐,如果在n秒之前返回了或点击了终止按钮就停止连接和播放音乐。
现在我的播放操作都是在httpwebrequest这个子线程里面实现的,但是要在主线程来终止连接。
可能说的有些混乱,希望高人指点下思路。

#4


有高人指点下不……先感谢啦。

#1


那就让它在主线程执行, 这样:
        public void DoClick(object sender, EventArgs e)
        {
            if (InvokeRequired) // 是否需要远程调用
            {
                Invoke(new Action<object, EventArgs>(DoClick), sender, e); return;
            }
            /// 主线程的代码
        }

#2


你好,我直接使用invoke报错了:
当前上下文中不存在名称“invoke”
你意思是不是使用类似于:textBox1.Invoke()这样执行呢?
我希望的是不和某控件捆绑使用,可能表达的不太正确,新手,谢谢。

#3


我最终的目的是这样的:
在HttpWebRequest异步连接的时候超过n秒钟就播放一个音乐,如果在n秒之前返回了或点击了终止按钮就停止连接和播放音乐。
现在我的播放操作都是在httpwebrequest这个子线程里面实现的,但是要在主线程来终止连接。
可能说的有些混乱,希望高人指点下思路。

#4


有高人指点下不……先感谢啦。