本帖最后由 wlhkane110 于 2014-01-03 10:12:55 编辑

解决方案 »

  1.   

    同意楼上的观点,你的播放功能是单线程播放的,在播放过程中,整个窗体也卡了,你的Mp3类也是单线程的。
    你可以试试WPF的MediaPlayer类,他会在另外的线程中进行播放,甚至可以同时播放多个。
      

  2.   

    我觉得你的问题不是单线程引起的,mci和api都不会阻塞。
      

  3.   

    试了下 其他事件都要等播放完毕后才会响应 感觉应该是单线程的问题
    我试着:
    Thread t = new Thread(new ThreadStart(mp3play));
    t.Start();
    这样来启动播放 没有声音 debug流程和参数都没错 不过就是没有播放
    此前没做过...正在研究中....
      

  4.   

    只能说明Mp3的play是不可中断的,Mp3中没有提供暂停吗
      

  5.   

    有的 暂停和停止都有 不过每个MP3都是很短的1、2秒 中断和暂停的感觉没用 我觉得关键是在于我在做其他操作时跳出foreach循环 或者直接停止了mp3play()
    就是不知道该怎么做
      

  6.   

    private Thread UIThread; //辅UI线程
    this.UIThread = new Thread(mp3play);
    this.UIThread.Start();
      

  7.   

    试了下 其他事件都要等播放完毕后才会响应 感觉应该是单线程的问题
    我试着:
    Thread t = new Thread(new ThreadStart(mp3play));
    t.Start();
    这样来启动播放 没有声音 debug流程和参数都没错 不过就是没有播放
    此前没做过...正在研究中....试了下 其他事件都要等播放完毕后才会响应 感觉应该是单线程的问题
    我试着:
    Thread t = new Thread(new ThreadStart(mp3play));
    t.Start();
    这样来启动播放 没有声音 debug流程和参数都没错 不过就是没有播放
    此前没做过...正在研究中....
    把MP3类Play函数贴出来看一下。
      

  8.   

    百度来的Mp3播放类:using System;
    using System.Runtime.InteropServices;
    using System.Text;
    using System.IO;
    using System.Windows.Forms;namespace WindowsApplication7
    {
        public class Mp3
        {
            public Mp3()
            {
            }        //定义API函数使用的字符串变量 
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
            private string Name = "";
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
            private string durLength = "";
            [MarshalAs(UnmanagedType.LPTStr, SizeConst = 128)]
            private string TemStr = "";
            int ilong;        //定义播放状态枚举变量
            public enum State
            {
                mPlaying = 1,
                mPuase = 2,
                mStop = 3
            };        //结构变量
            public struct structMCI
            {
                public bool bMut;
                public int iDur;
                public int iPos;
                public int iVol;
                public int iBal;
                public string iName;
                public State state;
            };        public structMCI mc = new structMCI();
            //取得播放文件属性
            public string FileName
            {
                get
                {
                    return mc.iName;
                }
                set
                {
                    //ASCIIEncoding asc = new ASCIIEncoding(); 
                    try
                    {
                        TemStr = "";
                        TemStr = TemStr.PadLeft(127, Convert.ToChar(" "));
                        Name = "";
                        Name = Name.PadLeft(260, Convert.ToChar(" "));
                        mc.iName = value;
                        ilong = APIClass.GetShortPathName(mc.iName, Name, Name.Length);
                        Name = GetCurrPath(Name);
                        //Name = "open " + Convert.ToChar(34) + Name + Convert.ToChar(34) + " alias media";
                        Name = "open " + Convert.ToChar(34) + Name + Convert.ToChar(34) + " alias media";
                        ilong = APIClass.mciSendString("close all", TemStr, TemStr.Length, 0);
                        ilong = APIClass.mciSendString(Name, TemStr, TemStr.Length, 0);
                        ilong = APIClass.mciSendString("set media time format milliseconds", TemStr, TemStr.Length, 0);
                        mc.state = State.mStop;
                    }
                    catch
                    {
                    }
                }
            }        //播放
            public void play()
            {
                TemStr = "";
                TemStr = TemStr.PadLeft(127, Convert.ToChar(" "));
                APIClass.mciSendString("play media", TemStr, TemStr.Length, 0);
                mc.state = State.mPlaying;
            }        //停止
            public void StopT()
            {
                TemStr = "";
                TemStr = TemStr.PadLeft(128, Convert.ToChar(" "));
                ilong = APIClass.mciSendString("close media", TemStr, 128, 0);
                ilong = APIClass.mciSendString("close all", TemStr, 128, 0);
                ilong = APIClass.mciSendString(Name, TemStr, TemStr.Length, 0);
                //ilong = APIClass.mciSendString("set media time format milliseconds", TemStr, TemStr.Length, 0);
                mc.state = State.mStop;
            }        public void Puase()
            {
                TemStr = "";
                TemStr = TemStr.PadLeft(128, Convert.ToChar(" "));
                ilong = APIClass.mciSendString("pause media", TemStr, TemStr.Length, 0);
                mc.state = State.mPuase;
            }        private string GetCurrPath(string name)
            {
                if (name.Length < 1) return "";
                name = name.Trim();
                name = name.Substring(0, name.Length - 1);
                return name;
            }        //总时间
            public int Duration
            {
                get
                {
                    durLength = "";
                    durLength = durLength.PadLeft(128, Convert.ToChar(" "));
                    APIClass.mciSendString("status media length", durLength, durLength.Length, 0);
                    durLength = durLength.Trim();
                    if (durLength == "") return 0;
                    return (int)(Convert.ToDouble(durLength) / 1000f);
                }
            }        public bool IsEnd()
            {
                durLength = "";
                durLength = durLength.PadLeft(128, Convert.ToChar(" "));
                APIClass.mciSendString("status media length", durLength, durLength.Length, 0);
                durLength = durLength.Trim();
                string curLength;
                curLength = "";
                curLength = curLength.PadLeft(128, Convert.ToChar(" "));
                APIClass.mciSendString("status media position", curLength, curLength.Length, 0);
                curLength = curLength.Trim();
                if (curLength == durLength)
                {
                    return true;
                }
                return false;
            }        //当前时间
            public int CurrentPosition
            {
                get
                {
                    durLength = "";
                    durLength = durLength.PadLeft(128, Convert.ToChar(" "));
                    APIClass.mciSendString("status media position", durLength, durLength.Length, 0);
                    durLength = durLength.Trim();
                    if (durLength == "")
                    {
                        return mc.iPos = 0;
                    }
                    mc.iPos = unchecked((int)(Convert.ToInt32(durLength) / 1000f));
                    return mc.iPos;
                }
            }
        }    public class APIClass
        {
            [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
            public static extern int GetShortPathName(
            string lpszLongPath,
            string shortFile,
            int cchBuffer
            );        [DllImport("winmm.dll", EntryPoint = "mciSendString", CharSet = CharSet.Auto)]
            public static extern int mciSendString(
            string lpstrCommand,
            string lpstrReturnString,
            int uReturnLength,
            int hwndCallback
            );
        }
    }如果另起一个线程的报错:
    “this.CurrentPosition”引发了“System.FormatException”类型的异常
    “this.Duration”引发了“System.NullReferenceException”类型的异常
      

  9.   

    如LS的MP3控制类 另起线程的异常代码:public string FileName
            {
                get
                {
                    return mc.iName;
                }
                set
                {
                    //ASCIIEncoding asc = new ASCIIEncoding(); 
                    try
                    {
                        TemStr = "";
                        TemStr = TemStr.PadLeft(127, Convert.ToChar(" "));
                        Name = "";
                        Name = Name.PadLeft(260, Convert.ToChar(" "));
                        mc.iName = value;
                        ilong = APIClass.GetShortPathName(mc.iName, Name, Name.Length);
                        Name = GetCurrPath(Name);
                        //Name = "open " + Convert.ToChar(34) + Name + Convert.ToChar(34) + " alias media";
                        Name = "open " + Convert.ToChar(34) + Name + Convert.ToChar(34) + " alias media";
                        ilong = APIClass.mciSendString("close all", TemStr, TemStr.Length, 0);                    //这里的话单线程正常 而另起线程的话到这步则没有正确得到结果 怎么回事呢?
                        ilong = APIClass.mciSendString(Name, TemStr, TemStr.Length, 0);                    ilong = APIClass.mciSendString("set media time format milliseconds", TemStr, TemStr.Length, 0);
                        mc.state = State.mStop;
                    }
                    catch
                    {
                    }
                }
            }
      

  10.   

    Quote: 引用 11 楼 wlhkane110 的回复:

    如LS的MP3控制类 另起线程的异常代码:
    调试,中断看一下mc.iName的值有没有变化。
      

  11.   

    没有变化 我做了个demo:yunpan.cn/QDaFPcGB2DXgu
    想不明白 明明各个参数都是一致的 不知道为什么另起线程就是不行
      

  12.   

    mciSendString需要一个消息泵(Message Loop),也就是说只有STA的线程可以工作,可以做如下修改:            Thread UIThread = new Thread((ThreadStart)delegate
                {
                    mp3play();
                });
                UIThread.SetApartmentState(ApartmentState.STA);
                UIThread.IsBackground = true;
                UIThread.Start();已测试。