当前位置: 代码迷 >> C# >> c# winform 多线程有关问题
  详细解决方案

c# winform 多线程有关问题

热度:53   发布时间:2016-05-05 02:35:57.0
c# winform 多线程问题
多线程项目中,已使用异步委托this.BeginInvoke,在公司测试正常,上线后使用中发生错误,导致程序崩溃,在线求助!

错误日志:
 时间: 2015-08-27 18:58:35 125
信息: System.AccessViolationException: 尝试读取或写入受保护的内存。这通常指示其他内存已损坏。
   在 System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
   在 System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)
   在 System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
   在 System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
   在 System.Windows.Forms.Application.RunDialog(Form form)
   在 System.Windows.Forms.Form.ShowDialog(IWin32Window owner)
   在 PosCtrl.UI.FrmTrade.ShowScanBagitemForm(Boolean blScanner, Boolean blWeightPLU, Decimal weight, Decimal expectweight, Decimal expecttolerance, String line, List`1 weightlist)

时间: 2015-08-27 18:58:35 187
信息: System.InvalidOperationException: 在创建窗口句柄之前,不能在控件上调用 Invoke 或 BeginInvoke。
   在 System.Windows.Forms.Control.MarshaledInvoke(Control caller, Delegate method, Object[] args, Boolean synchronous)
   在 System.Windows.Forms.Control.BeginInvoke(Delegate method, Object[] args)
   在 PosCtrl.UI.FrmBagItem.Monitoring()
   在 System.Threading.ThreadHelper.ThreadStart_Context(Object state)
   在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   在 System.Threading.ThreadHelper.ThreadStart()
------解决思路----------------------
            
while (!this.IsHandleCreated)
            {
                Thread.Sleep(100);
            }

            this.BeginInvoke();

------解决思路----------------------
我看你像是调用了非托管代码了吧,这应该是两次调用之间的时间间隔小于了资源回收的速度才会导致这个问题,你检查一下这些非托管代码的资源回收方式(CallingConvention设置),没设的话必须要设一下,原先如果是stdcall调用,换成cdecl调用,就是托管代码调用还由非托管调用释放。
所以,你就检查两点:
1、调用时间间隔是不是太小了,如果是就控制一下
2、检查调用方的资源释放方式。
------解决思路----------------------
你更新UI控件的最高频率是多少?不是单线程,是所有线程合并到UI的更新速度。
不能太快,有极限值的,超过了,就卡死。
------解决思路----------------------
又是“先滥用死循环,然后导致滥用线程,然后导致一堆冲突,然后滥用一堆阻塞,然后导致还没怎么操作就卡死”的想象。

这种事情,应该从你的根上去重新设计。从你的“A窗口,启动线程ThreadA(监控外部输入,例如全局变量x),当满足某一条件时.......,当满足某一条件时.......”这里改!
  相关解决方案