System.NullReferenceException 郁闷的问题 急等解决方法

wolf_Knight 2010-02-01 05:18:31
wince 5.0 下面 c# 开发的系统,主界面有5个线程同时在运行,其中有个线程是在移动lable(跑马灯效果),其中有个线程是在每隔一段时间给picturebox更换图片。每个5线程入口,调用方法都使用了try catch 结构捕捉错误。
问题是程序运行一段时间(2-3小时或者更长),程序弹出System.NullReferenceException错误对话框,指向我程序的入口,如:at test.main().而我做的try catch 根本捕捉不到此错误。后来用了CurrentDomain.UnhandledException才捕捉到,但是还是不知道该错误是哪个线程出的错,该错误对话框一出,程序就挂了。

求大侠指点。谢谢啊。
...全文
657 22 打赏 收藏 转发到动态 举报
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
wolf_Knight 2010-02-08
  • 打赏
  • 举报
回复
自己解决,散分。。。。。。
不老神仙 2010-02-02
  • 打赏
  • 举报
回复
也遇到这个问题 关注中...
wolf_Knight 2010-02-02
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 ouc_ajax 的回复:]
代码有点多,也没看出什么问题来。

多线程的时候调试本来就很麻烦的,楼主试试线程的加锁吧,你好像都没有注意线程安全的问题。
会不会线程不同,导致调用出现逻辑异常!
[/Quote]

呵呵。谢谢你的提醒,我也考虑过这个问题,但是我不知道这个锁应该加在什么地方。所以我现在暂时是做了错误处理。如果出错了。重新播放。
ouc_ajax 2010-02-02
  • 打赏
  • 举报
回复
代码有点多,也没看出什么问题来。

多线程的时候调试本来就很麻烦的,楼主试试线程的加锁吧,你好像都没有注意线程安全的问题。
会不会线程不同,导致调用出现逻辑异常!
じоνё靁〃 2010-02-02
  • 打赏
  • 举报
回复
我也给你顶一下,比较复杂,还是自己看看吧。
wolf_Knight 2010-02-02
  • 打赏
  • 举报
回复
顶一下
wangan2008 2010-02-02
  • 打赏
  • 举报
回复
up
wolf_Knight 2010-02-02
  • 打赏
  • 举报
回复

/// <summary>
/// 调用接口播放视频
/// </summary>
/// <returns></returns>
protected bool PlayClip()
{
try
{

CloseInterfaces();

if (!GetInterfaces())
return false;

CheckClipType();
if (clipType == AppEnum.ClipType.None)
return false;

if (mediaEvt == null || videoWin == null || mediaCtl==null) return false;

int hr = mediaEvt.SetNotifyWindow(GetThisHandle(), WM_GRAPHNOTIFY, IntPtr.Zero);

videoWin.put_Owner(GetThisHandle());
// videoWin.put_WindowStyle();

videoWin.put_WindowStyle(WindowStyle.Border);
videoWin.SetWindowPosition(0, 0, 300, 260);
//GetFrameStepInterface();
hr = mediaCtl.Run();
if (hr >= 0)
playState = AppEnum.PlayState.Running;

return hr >= 0;
}
catch (Exception ee)
{
// MessageBox.Show("Could not start clip\r\n" + ee.Message);
ErrorDeal = true;
Util.WriteError(ee.Message + " " + ee.StackTrace.ToString(), "VideoPlay.PlayClip");
return false;
}
}

/// <summary>
/// 获取视频播放接口
/// </summary>
/// <returns></returns>
protected bool GetInterfaces()
{
Type comtype = null;
object comobj = null;

int hr = 0;
try
{

comtype = Type.GetTypeFromCLSID(xClsid.Clsid_FilterGraph);


if (comtype == null)
{
Util.WriteError("DirectX no Exists", "VideoPlay GetInterfaces");
return false;
}

comobj = Activator.CreateInstance(comtype);

graphBuilder = (IGraphBuilder)comobj;
comobj = null;

string playfile = PlayPath + VideoSouces[SetFile];


hr = graphBuilder.RenderFile(playfile, null);
if (hr < 0)
{
Util.WriteError("MarShal.ThrowException", "graphBuilder.RenderFile");
return false;
}

mediaCtl = (IMediaControl)graphBuilder;
mediaEvt = (IMediaEventEx)graphBuilder;
mediaSeek = (IMediaSeeking)graphBuilder;
mediaPos = (IMediaPosition)graphBuilder;

videoWin = graphBuilder as IVideoWindow;
basicVideo = graphBuilder as IBasicVideo2;
basicAudio = graphBuilder as IBasicAudio;

return true;
}
catch (Exception ee)
{

Util.WriteError(ee.Message + " " + ee.StackTrace.ToString(), "VideoPlay.GetInterfaces");
ErrorDeal = true;
return false;
}
finally
{
if (comobj != null)
Marshal.ReleaseComObject(comobj);
comobj = null;

}
}

protected IntPtr GetThisHandle()
{
try
{
if (this.InvokeRequired)
{
GetHandle Tinvo = new GetHandle(GetThisHandle);
return ((IntPtr)this.Invoke(Tinvo));

}
else
{
return this.Handle;
}
}
catch (Exception ex)
{

Util.WriteError(ex.Message, "VideoPlay.GetThisHandle");
return IntPtr.Zero;
}

}

protected void CheckClipType()
{
try
{
if (basicAudio == null)
clipType = AppEnum.ClipType.None;
else
clipType = AppEnum.ClipType.AudioOnly;

if ((videoWin == null) || (basicVideo == null))
return;

OABool visible;
int hr = videoWin.get_Visible(out visible);
if (hr < 0)
return;
else
{
if (basicAudio == null)
clipType = AppEnum.ClipType.VideoOnly;
else
clipType = AppEnum.ClipType.AudioVideo;
}
}
catch (Exception ex)
{
Util.WriteError(ex.Message, "VideoPlay.CheckClipType");
}
}

#endregion

}
}
代码稍微说明一下:
请大家从RunVideo这个方法开始看:
这个方法先初始化数据,然后开始一个播放线程和一个监控线程,播放线程 先关闭direct一些接口类,然后再打开,开始播放,播放标志为flase ,监控播放线程如果监控播放完,再把播放标志为true,播放线程再播放下一个文件。


wolf_Knight 2010-02-02
  • 打赏
  • 举报
回复

protected void SetPlay()
{
EventCode code;

int p1, p2, hr;

while (ThreadState == true)
{

try
{

if (mediaEvt != null)
{

hr = mediaEvt.GetEvent(out code, out p1, out p2, 0);


if (hr >= 0)
{

hr = mediaEvt.FreeEventParams(code, p1, p2);


if (code == EventCode.Complete)
{

OnClipCompleted();

Thread.Sleep(3000);
}
}
}
if (ErrorDeal == true) //如果播放线程出现错误,重新开始播放
{
ErrorDeal = false;
SetFile = 0;
threadPlayVideo = true;// 继续播放
Thread.Sleep(200);
Util.WriteError("Video Play Com","Error Deal");
}

}
catch (Exception ex)
{
//throw new Exception(ex.Message);

Util.WriteError("[" + itest.ToString() + "]" + ex.ToString() + " " + ex.StackTrace.ToString(), " videoPlay SetPlay");
}


}

}

/// <summary>
/// 线程监控是否视频播放完成
/// </summary>
protected void OnClipCompleted()
{

try
{
if ((mediaCtl == null) || (mediaSeek == null))

return;

int hr = mediaCtl.Stop();

SetFile++; //播放下一个文件
if (SetFile >= icount)
{

SetFile = 0;

}
threadPlayVideo = true;


}
catch (Exception ex)
{

Util.WriteError(ex.ToString() + " " + ex.StackTrace.ToString(), "OnClipCompleted");
is_play = false;
ThreadState = false;
VideoPlayerLoop = false;
threadPlayVideo = false;
}
finally
{

}
}


#endregion

#region 播放接口
/// <summary>
/// 关闭接口
/// </summary>
protected void CloseInterfaces()
{
int hr;
try
{
if (mediaCtl != null)
{
hr = mediaCtl.StopWhenReady();
mediaCtl = null;
}

playState = AppEnum.PlayState.Stopped;
if (mediaEvt != null)
{
hr = mediaEvt.SetNotifyWindow(IntPtr.Zero, WM_GRAPHNOTIFY, IntPtr.Zero);
mediaEvt = null;
}
if (videoWin != null)
{
hr = videoWin.put_Visible(OABool.False);
//hr = videoWin.put_Visible(0);
hr = videoWin.put_Owner(IntPtr.Zero);
videoWin = null;
}


mediaSeek = null;
mediaPos = null;

basicVideo = null;
//videoStep = null;
basicAudio = null;

if (graphBuilder != null)
{
Marshal.ReleaseComObject(graphBuilder);
}
graphBuilder = null;

playState = AppEnum.PlayState.Init;
}
catch (Exception ex)
{
//ErrorDeal = true;
Util.WriteError(ex.Message, "VideoPlay.CloseInterfaces");
}
}

public void CloseClip(string errcode)
{
int i = 0;
try
{

clipType = AppEnum.ClipType.None;

CloseInterfaces();

SetThisRefresh();

}
catch (Exception ex)
{
Util.WriteError( errcode + " " + ex.Message, "VideoPlay.CloseClip");
}

}

wolf_Knight 2010-02-02
  • 打赏
  • 举报
回复

/// <summary>
/// 播放视频方法
/// </summary>
public void NewPlay()
{
try
{
CloseClip("NewPlay1");
clipType = AppEnum.ClipType.None;
if (!PlayClip())
CloseClip("NewPlay2");
}
catch (Exception ex)
{
ErrorDeal = true;
Util.WriteError(ex.Message, "NewPlay");

}
}

/// <summary>
/// 视频是否正在播放
/// </summary>
public bool ISPlay
{
get
{
return is_play;
}
set
{
if (is_play == value)
return;
is_play = value;
}

}



/// <summary>
/// 外部执行播放视频
/// </summary>
public void RunVideo()
{

try
{
//初始数据
if (IniPlayData())
{

//启动播放视频线程
Exec_Play();
//启动监控视频线程
StartPlay();
}
}
catch (Exception ex)
{
Util.WriteError(ex.Message + " " + ex.StackTrace.ToString(), "RunVideo");
}
}




#region 视频监控线程
protected void StartPlay()
{
try
{

ts = new Thread(new ThreadStart(SetPlay));
ts.IsBackground = true;
ThreadState = true;

ts.Start();

}
catch (Exception ex)
{
//MessageBox.Show("Video:" + ex.Message);
Util.WriteError(ex.Message, "Video.StartPlay");
}
}

hyfzz123 2010-02-02
  • 打赏
  • 举报
回复
upupu
wolf_Knight 2010-02-02
  • 打赏
  • 举报
回复

using DirectShow; //封装了direct接口类
namespace test.UserControls
{
public partial class VideoPlay : UserControl
{
#region 基本变量
Guid FilterGraph = new Guid("e436ebb3-524f-11ce-9f53-0020af0ba770");
protected int set_file;
private IntPtr hdl;
protected delegate void EventShowTxt(string strMessage);
protected delegate void SetRefresh();
protected delegate IntPtr GetHandle();
IGraphBuilder graphBuilder;
private IVideoWindow videoWin;
private IBasicVideo basicVideo;
private IBasicAudio basicAudio;
private IMediaControl mediaCtl;
private IMediaEventEx mediaEvt;
private IMediaSeeking mediaSeek;
private IMediaPosition mediaPos;

private int icount = 0;

protected Thread ts = null;
protected Thread tsplay = null;
protected bool VideoPlayerLoop; //视频播放线程标志
protected bool ErrorDeal = false;
protected bool threadPlayVideo = false;

private const int WM_GRAPHNOTIFY = 0x00008001;
private const int WS_CHILD = 0x40000000;
private const int WS_CLIPCHILDREN = 0x02000000;
private const int WS_CLIPSIBLINGS = 0x04000000;
private bool thread_state;

private AppEnum.PlayState playState;
private AppEnum.ClipType clipType;
private AppEnum.ClipType ini_clip_type;
public AppEnum.MainVideoPlayState SetPlayState;
private bool is_play;
private string[] video_souces;
private string[] video_play_by_code;
private string play_path;
private int play_by_code_int;



#endregion

#region 属性


public string[] VideoSouces
{
get
{
return video_souces;
}
set
{
if (video_souces == value)
return;
video_souces = value;
}
}


public string PlayPath
{
get
{
return play_path;
}
set
{
if (play_path == value)
return;
play_path = value;
}
}



public int SetFile
{
set
{
if (set_file == value)
return;
set_file = value;
}
get
{
return set_file;
}
}
#region 方法
#region 视频播放线程
/// <summary>
/// TODO 开始加载数据
/// </summary>
protected void Exec_Play()
{

//TODO 初始化数据
try
{

hdl = this.Handle;
ISPlay = true;
VideoPlayerLoop = true;
ErrorDeal = false;
threadPlayVideo = true;
tsplay = new Thread(new ThreadStart(FirstPlay));
tsplay.IsBackground = true;
tsplay.Start();
}
catch (Exception ex)
{
Util.WriteError(ex.Message + "" + ex.StackTrace.ToString(), "Exec_Play");
}


}

/// <summary>
/// 视频播放线程
/// </summary>
protected void FirstPlay()
{

while (VideoPlayerLoop == true)
{
if (threadPlayVideo == true)
{
threadPlayVideo = false;
try
{
NewPlay();
}
catch (Exception ex)
{
ErrorDeal = true;
Util.WriteError(ex.Message, "VideoPlay.FirstPlay");
}
}
Thread.Sleep(300);

}

}

/// <summary>
/// 初始播放数据
/// </summary>
/// <returns></returns>
protected bool IniPlayData()
{
try
{

SetFile = 0;
if (VideoSouces == null || VideoSouces.Length == 0)
return false;
icount = VideoSouces.Length;

return true;
}
catch (Exception ex)
{

Util.WriteError(ex.Message + " " + ex.StackTrace.ToString(), "IniPlayData");
return false;
}
}

#endregion

protected void SetThisRefresh()
{
try
{
if (this.InvokeRequired)
{
SetRefresh cj = new SetRefresh(SetThisRefresh);
this.Invoke(cj);
}
else
{
this.Refresh();
}
}
catch (Exception ex)
{
Util.WriteError(ex.Message, "VideoPlay.SetThisRefresh");
}

}


wolf_Knight 2010-02-02
  • 打赏
  • 举报
回复
我把问题再描述的详细一些。
我把主界面所有代码再仔细的看了下。其中我有这样一个功能:
一个线程是用c#调用direct接口来播放视频,
另外一个线程来监控视频是否播放完成,
如果播放完成,接着播放下个文件。
根据System.NullReferenceException 这个错误,我猜想是不是因为这样的原因,播放线程正在执行,而监控播放是否完成的线程可能监控到播放已经完成,释放了接口类,而播放线程可能正在调用某个方法,所以会有这样的问题。请大家帮我看看代码,如果看不明白的地方,请贴出来。如果发现有漏洞,请帮忙看下怎么解决。谢谢大家了。代码如下:
wolf_Knight 2010-02-02
  • 打赏
  • 举报
回复
顶一下
wolf_Knight 2010-02-02
  • 打赏
  • 举报
回复
期待大侠指点...
cuike519 2010-02-01
  • 打赏
  • 举报
回复
放点断言(Debug.Assert)语句判断一下吧,或者使用日志跟踪一下。
wolf_Knight 2010-02-01
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 jimh 的回复:]
看e.Stack,里面有详细信息

[/Quote]

wince 下面 没有这个,只有如下:
e.Equals;
e.ExceptionObject(属性)
e.GetHashCode;
e.GetType;
e.IsTerminating(属性)
e.ToString;
jimh 2010-02-01
  • 打赏
  • 举报
回复
看e.Stack,里面有详细信息
wolf_Knight 2010-02-01
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 zhujiazhi 的回复:]
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);

void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            throw new NotImplementedException();
        }
[/Quote]

我用的是:
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);

void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
//throw new NotImplementedException();
messagebox.show(e.Tostring());
}

它没有告诉我哪个线程出错,只是说 error at test.exe at test.main() main是程序入口
zhujiazhi 2010-02-01
  • 打赏
  • 举报
回复
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);

void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
throw new NotImplementedException();
}
加载更多回复(2)

110,536

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧