winform 有办法在事件处理过程中中断事件并处理其他事件吗? 本帖最后由 wlhkane110 于 2014-01-03 10:12:55 编辑 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 同意楼上的观点,你的播放功能是单线程播放的,在播放过程中,整个窗体也卡了,你的Mp3类也是单线程的。你可以试试WPF的MediaPlayer类,他会在另外的线程中进行播放,甚至可以同时播放多个。 我觉得你的问题不是单线程引起的,mci和api都不会阻塞。 试了下 其他事件都要等播放完毕后才会响应 感觉应该是单线程的问题我试着:Thread t = new Thread(new ThreadStart(mp3play));t.Start();这样来启动播放 没有声音 debug流程和参数都没错 不过就是没有播放此前没做过...正在研究中.... 只能说明Mp3的play是不可中断的,Mp3中没有提供暂停吗 有的 暂停和停止都有 不过每个MP3都是很短的1、2秒 中断和暂停的感觉没用 我觉得关键是在于我在做其他操作时跳出foreach循环 或者直接停止了mp3play()就是不知道该怎么做 private Thread UIThread; //辅UI线程 this.UIThread = new Thread(mp3play); this.UIThread.Start(); 试了下 其他事件都要等播放完毕后才会响应 感觉应该是单线程的问题我试着:Thread t = new Thread(new ThreadStart(mp3play));t.Start();这样来启动播放 没有声音 debug流程和参数都没错 不过就是没有播放此前没做过...正在研究中....试了下 其他事件都要等播放完毕后才会响应 感觉应该是单线程的问题我试着:Thread t = new Thread(new ThreadStart(mp3play));t.Start();这样来启动播放 没有声音 debug流程和参数都没错 不过就是没有播放此前没做过...正在研究中....把MP3类Play函数贴出来看一下。 百度来的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”类型的异常 如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 { } } } Quote: 引用 11 楼 wlhkane110 的回复:如LS的MP3控制类 另起线程的异常代码:调试,中断看一下mc.iName的值有没有变化。 没有变化 我做了个demo:yunpan.cn/QDaFPcGB2DXgu想不明白 明明各个参数都是一致的 不知道为什么另起线程就是不行 mciSendString需要一个消息泵(Message Loop),也就是说只有STA的线程可以工作,可以做如下修改: Thread UIThread = new Thread((ThreadStart)delegate { mp3play(); }); UIThread.SetApartmentState(ApartmentState.STA); UIThread.IsBackground = true; UIThread.Start();已测试。 C#里面什么时候使用索引呀 【大侠们】帮个忙 关于字符串格式 C# 如何访问共享文件 请问如何将一个01字符串转换为数字 这里有了解AS2协议(也不知道该不该这么说)的达人吗? 如何让DataGridBoolColumn 在每个单元格中只包含两个状态的复选框即:已选中(true)、未选中(false),而没有和 DBNull.Value? 请问windows8平板开发如何入门?有相关的资料吗? c#如何理解方法调用 dateTimePicker能表现出季度的形式吗,比如2004年1季度 NPOI 强制转换问题。 局域网内操作word的问题 C# dataGridView控件的问题
你可以试试WPF的MediaPlayer类,他会在另外的线程中进行播放,甚至可以同时播放多个。
我试着:
Thread t = new Thread(new ThreadStart(mp3play));
t.Start();
这样来启动播放 没有声音 debug流程和参数都没错 不过就是没有播放
此前没做过...正在研究中....
就是不知道该怎么做
this.UIThread = new Thread(mp3play);
this.UIThread.Start();
我试着:
Thread t = new Thread(new ThreadStart(mp3play));
t.Start();
这样来启动播放 没有声音 debug流程和参数都没错 不过就是没有播放
此前没做过...正在研究中....试了下 其他事件都要等播放完毕后才会响应 感觉应该是单线程的问题
我试着:
Thread t = new Thread(new ThreadStart(mp3play));
t.Start();
这样来启动播放 没有声音 debug流程和参数都没错 不过就是没有播放
此前没做过...正在研究中....
把MP3类Play函数贴出来看一下。
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”类型的异常
{
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
{
}
}
}
想不明白 明明各个参数都是一致的 不知道为什么另起线程就是不行
{
mp3play();
});
UIThread.SetApartmentState(ApartmentState.STA);
UIThread.IsBackground = true;
UIThread.Start();已测试。