小弟是菜鸟,最近在学习C#,想写一个定时播放声音的小东西。定时使用的System.Timers.Timer,播放用的winmm.dll,然后发现,定时时能做弹出对话框之类的操作,也能通过单击按钮来播放MP3,但是就是不能定时来执行播放函数。下面是源代码,哪位兄台帮忙看下,分数送上。感激不尽。using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.IO;namespace Timer_Music
{
    public partial class beep : Form
    {
        private bool done = false;
        string nowTimeText = "";
        System.Timers.Timer t;
        clsMCI mp = new clsMCI();
                public beep()
        {
            InitializeComponent();
        }        private void Form1_SizeChanged(object sender, EventArgs e)
        {
            if (this.WindowState == FormWindowState.Minimized)
            {
                this.Hide();
                this.notifyIcon1.Visible = true;
            }
        }        private void notifyIcon1_MouseClick(object sender, MouseEventArgs e)
        {
            this.Visible = true;
            this.WindowState = FormWindowState.Normal;
            this.notifyIcon1.Visible = false;
        }        private void beep_Load(object sender, EventArgs e)
        {
            HourText.Text = DateTime.Now.Hour < 10 ? "0" + DateTime.Now.Hour.ToString() : DateTime.Now.Hour.ToString();
            MinuteText.Text = DateTime.Now.Minute < 10 ? "0" + DateTime.Now.Minute.ToString() : DateTime.Now.Minute.ToString();
            SecondText.Text = DateTime.Now.Second < 10 ? "0" + DateTime.Now.Second.ToString() : DateTime.Now.Second.ToString();
        }
        
//开始定时
        private void button1_Click(object sender, EventArgs e)
        {
            nowTimeText = HourText.Text + ":" + MinuteText.Text + ":" + SecondText.Text;
            button1.Enabled = false;
            StartTimer();
            //mp.play(); 这里能直接播放
        }        //开始侦听
        private void StartTimer()
        {
            try
            {
                t = new System.Timers.Timer(1000);
                t.AutoReset = true;
                t.Elapsed += new System.Timers.ElapsedEventHandler(PlayMusic);
                t.Enabled = true;
            }
            catch
            {
                MessageBox.Show("Error!");
            }
        }        
        //播放
        public void PlayMusic(object source, System.Timers.ElapsedEventArgs e)
        {
            if (nowTimeText == DateTime.Now.ToLongTimeString() && done == false)
            {
                
                try
                {
                    //MessageBox.Show(DateTime.Now.ToLongTimeString() + nowTimeText + "is now");
                    mp.play();
                }
                catch
                {
                    MessageBox.Show("Error!");
                }
            }
        }
        //结束
        private void StopTimer()
        {
            done = true;
            button1.Enabled = true;
        }        private void button2_Click(object sender, EventArgs e)
        {
            StopTimer();
        }        private void beep_FormClosing(object sender, FormClosingEventArgs e)
        {
            t.Dispose();
        }        private void button3_Click(object sender, EventArgs e)
        {
            try
            {
                openFileDialog1.Filter = "*.mp3|*.mp3";
                openFileDialog1.FileName = "";
                if (openFileDialog1.ShowDialog() == DialogResult.OK)
                {
                    mp.FileName = openFileDialog1.FileName;
                    PlayFileName.Text = openFileDialog1.FileName;
                }
            }
            catch
            {
                MessageBox.Show("出错错误!");
            }
        }
    }
    public class clsMCI
    {
        public clsMCI()
        {
            //
            // TODO: 在此处添加构造函数逻辑
            //
        }        //定义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.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";
                    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
                {
                    MessageBox.Show("出错错误!");
                }
            }
        }
        
//播放
        public void play()
        {
            TemStr = "";
            TemStr = TemStr.PadLeft(127, Convert.ToChar(" "));
            APIClass.mciSendString("play media", TemStr, TemStr.Length, 0);
            mc.state = State.mPlaying;
        } //获得当前路径
private string GetCurrPath(string name)
        {
            if (name.Length < 1) return "";
            name = name.Trim();
            name = name.Substring(0, name.Length - 1);
            return name;
        }
}    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
        );
    }
}

解决方案 »

  1.   

    恩我也遇到过这样的。不按照timer定义的时间运行。。甚至会出现一直都不运行的情况。。发帖子问过。不过没人解决
      

  2.   

    c#有三个Timer类,建议用System.Thread.Timer和回调函数。并参考:http://msdn.microsoft.com/zh-cn/library/system.threading.timer.aspx
      

  3.   

    C#有三个Timer,建议使用System.Thread.Timer类,参考http://msdn.microsoft.com/zh-cn/library/system.threading.timer.aspx
      

  4.   

    感谢楼上这位兄台的热心回答,但是我用了System.Thread.Timer,效果是一样的。而且触发的时间感觉很不准确。
    加分求解啊。哪位大侠能帮帮忙?
      

  5.   

    点button1不能播放?
    查下这个条件if (nowTimeText == DateTime.Now.ToLongTimeString() && done == false)单步调试一下,看看nowTimeText的值是什么
      

  6.   

    PlayMusic()
    方法中设个断点.看看到底是执行不执行
      

  7.   

    winForm中用System.Windows.Forms.Timer就行private System.Windows.Forms.Timer timer1;
     
    timer1.Enabled = true;
    this.timer1.Tick += new System.EventHandler(this.timer1_Tick);private void timer1_Tick(object sender, EventArgs e)
            {
                //....
            }
      

  8.   

    标准的计时器啊。有两个参数:第一个是创建Timer对象时实际等待多长时间后才运行,第二个参数是时间间隔Interval。
      

  9.   

    另,在多线程时,有时间不准的现象。“系统设置线程不可调度的时间只是‘近似于’所设定的毫秒数。没错,如果告诉系统想睡眠100ms,那么线程将睡眠差不多这么长时间,但是可能会长达数秒甚至数分钟。”这是Jeffrey在《Windows核心编程(第5版)》讲述“睡眠”(P169)时的一段话。不知道是否解释时间不准确的现象。
      

  10.   

    TO 5 楼的兄台:值是我所期望的值。
    TO 6 楼的兄台:在PlayMusic中我试着直接使用MessageBox.Show(),都能秀出对话框来,说明是能执行PlayMusic的。
    TO 7 楼的兄台:三个Timer我都试过了,但是都不能播放。
    TO 8、9 楼的兄台:我看过System.Thread.Timer的参数,就是在使用这个Timer的时候使用MessageBox.Show发现秀出来的BOX很不准时。我个人感觉可能是下面的播放的类有一些问题,那个是在网上抄的一段代码,现在想求哪位大侠能看看这个类是不是有问题。或者说能不能给我一个更好的播放MP3的办法。
    再次拜谢.
      

  11.   

    我看那个条件未必成立,你点了按钮后,记下了点击的时间,到timer启动的时间,可能会相差一秒
    你不妨把那个判断条件去掉试试
      

  12.   


                if (nowTimeText == DateTime.Now.ToLongTimeString() && done == false)明白你这个时间在这里的意义,不过,这样写并不好,建议用一个bool变量来表示。bool playNow=false; 
            private void button1_Click(object sender, EventArgs e) 
            { 
                nowTimeText = HourText.Text + ":" + MinuteText.Text + ":" + SecondText.Text; 
                button1.Enabled = false;
                playNow=true;//加上这句。 
                StartTimer(); 
                //mp.play(); 这里能直接播放 
            }         //播放 
            public void PlayMusic(object source, System.Timers.ElapsedEventArgs e) 
            { 
                if (playNow&& !done) 
                { 
                    playNow=false;                
                    try 
                    { 
                        //MessageBox.Show(DateTime.Now.ToLongTimeString() + nowTimeText + "is now"); 
                        mp.play(); 
                    } 
                    catch 
                    { 
                        MessageBox.Show("Error!"); 
                    } 
                } 
            } 
      

  13.   


    不好意思,搞错了。。
    //MessageBox.Show(DateTime.Now.ToLongTimeString() + nowTimeText + "is now"); 
    这个能出来的话,那你得跟一跟Play()方法,看有没有执行到。。
      

  14.   

    this.timer1.Tick+=new EventHandler(timer1_Tick);
    private void timer1_Tick(object sender, EventArgs e) 
            { 
                //在这里开始播放
            } 
      

  15.   

    大家都建议用Window.Forms.Timer,我去试下。
    谢谢Min_jie的热心回答,我跟下看看play()行不行。哪位大侠之前做过这个的,能不能给个范例?
      

  16.   

    给你参考一下这个结合委托来做的定时代码文章:
    http://blog.csdn.net/lfywy/archive/2008/07/16/2658623.aspx
      

  17.   

    这个问题很简单,搂主的经验不老到,这么多人都没注意这个小的逻辑问题
                if (nowTimeText == DateTime.Now.ToLongTimeString() && done == false) 
    变成
                if (nowTimeText <= DateTime.Now.ToLongTimeString() && done == false) 
    时间和double类似的,不要用“==”,要用误差判断或者不等量判断,比如“>= ”、“<=”,Timer事件本身的时间不是精确的,你用等量精确判断,出错是经常的
      

  18.   

    楼主是通过调用API来实现的怎么感觉你写的那么复杂啊,你可以先将其它多余的代码去掉,像你的设置的托盘等..
    单做个在timer中设置定时播放音乐的,那样看着不是更明了,或单独写到一个类中,用的时候调用
    你这样的集结代码很难排错的
      

  19.   

    我上边的说法指出了错误,不过你这里这样改不行,只是指出了你经常忘记的重要方面。你这里,按照我上边的改法,容易造成过了你的要求时间点,每一秒播放一次你的音乐,你还要想办法只播放一次音乐,感觉加个是否播放的变量就可以了,具体怎么做,搂住自己努力下。
    判断时间还可以用类似绝对值的方法比如要判断的2个时间dt1,dt2,那么(long)((TimeSpan)(dt1- dt2)).TotalSeconds<3,表示dt1和dt2相差不超过3s,但是具体处理时间判断得问题应该还是用一个时间大于或者小于,然后更新其中一个参加判断的时间的方式更常用。 
      

  20.   

    Math.Abs(((TimeSpan)(dt1- dt2)).TotalSeconds) <3
      

  21.   

    感谢各位的热心回答.问题已经解决了.
    主要是TIMER的问题,使用FORM的TIMER问题解决了.
    核心问题是使用System.Timer.Timer的时候要求使用参数,而把参数给了PLAYMUSIC后就后导致执行不成功.