非UI现场数据计算更新UI线程

lovetsfuer 2014-07-09 05:11:37
目前做法,非UI线程进行数据计算,计算的数据显示到UI线程上,
问题:非UI线程thread2整个运行一圈需要55~63秒

//线程
thread2 = new Thread(new ThreadStart(UpdateForm));
thread2.IsBackground = true;
thread2.Start();
//线程方法
public void UpdateForm()
{
while (tj2)
{
...
if (mycom1.IsOpen)
{
.....
MyClass.ThreadUI.SetTxt(TXTValue1, "-" + num.ToString(), this);
}
....
}
}

如果把thread2线程内计算方法分出来一部分,多个非UI线程对一个UI线程,就会报异常,我的理解是多个对UI线程进行操作照成的异常?有没有合理的方法?
System.OutOfMemoryException: 引发类型为“System.OutOfMemoryException”的异常。
在 System.Windows.Forms.UnsafeNativeMethods.SetWindowLongPtr32(HandleRef hWnd, Int32 nIndex, WndProc wndproc)
在 System.Windows.Forms.UnsafeNativeMethods.SetWindowLong(HandleRef hWnd, Int32 nIndex, WndProc wndproc)
在 System.Windows.Forms.NativeWindow.AssignHandle(IntPtr handle, Boolean assignUniqueID)
在 System.Windows.Forms.NativeWindow.AssignHandle(IntPtr handle)
在 System.Windows.Forms.NativeWindow.WindowClass.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
在 System.Windows.Forms.UnsafeNativeMethods.IntCreateWindowEx(Int32 dwExStyle, String lpszClassName, String lpszWindowName, Int32 style, Int32 x, Int32 y, Int32 width, Int32 height, HandleRef hWndParent, HandleRef hMenu, HandleRef hInst, Object pvParam)
在 System.Windows.Forms.UnsafeNativeMethods.CreateWindowEx(Int32 dwExStyle, String lpszClassName, String lpszWindowName, Int32 style, Int32 x, Int32 y, Int32 width, Int32 height, HandleRef hWndParent, HandleRef hMenu, HandleRef hInst, Object pvParam)
在 System.Windows.Forms.NativeWindow.CreateHandle(CreateParams cp)
在 System.Windows.Forms.Control.CreateHandle()
在 System.Windows.Forms.Control.RecreateHandleCore()
在 System.Windows.Forms.PictureBox.set_BorderStyle(BorderStyle value)
在 BoteDynamo.BoteThreadUI.SetBorderStyle[TObject](TObject objCtrl, BorderStyle style, Dynamo winf)
在 BoteDynamo.Dynamo.pic_MouseLeave(Object sender, EventArgs e)
在 System.Windows.Forms.Control.OnMouseLeave(EventArgs e)
在 System.Windows.Forms.Control.WmMouseLeave(Message& m)
在 System.Windows.Forms.Control.WndProc(Message& m)
在 System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
在 System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
在 System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
System.OutOfMemoryException: 引发类型为“System.OutOfMemoryException”的异常。
在 System.Windows.Forms.UnsafeNativeMethods.SetWindowLongPtr32(HandleRef hWnd, Int32 nIndex, WndProc wndproc)
在 System.Windows.Forms.UnsafeNativeMethods.SetWindowLong(HandleRef hWnd, Int32 nIndex, WndProc wndproc)
在 System.Windows.Forms.NativeWindow.AssignHandle(IntPtr handle, Boolean assignUniqueID)
在 System.Windows.Forms.NativeWindow.AssignHandle(IntPtr handle)
在 System.Windows.Forms.NativeWindow.WindowClass.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
在 System.Windows.Forms.UnsafeNativeMethods.IntCreateWindowEx(Int32 dwExStyle, String lpszClassName, String lpszWindowName, Int32 style, Int32 x, Int32 y, Int32 width, Int32 height, HandleRef hWndParent, HandleRef hMenu, HandleRef hInst, Object pvParam)
在 System.Windows.Forms.UnsafeNativeMethods.CreateWindowEx(Int32 dwExStyle, String lpszClassName, String lpszWindowName, Int32 style, Int32 x, Int32 y, Int32 width, Int32 height, HandleRef hWndParent, HandleRef hMenu, HandleRef hInst, Object pvParam)
在 System.Windows.Forms.NativeWindow.CreateHandle(CreateParams cp)
在 System.Windows.Forms.Control.CreateHandle()
在 System.Windows.Forms.Control.RecreateHandleCore()
在 System.Windows.Forms.PictureBox.set_BorderStyle(BorderStyle value)
在 ThreadUI.SetBorderStyle[TObject](TObject objCtrl, BorderStyle style, Dynamo winf)
在 Dynamo.pic_MouseLeave(Object sender, EventArgs e)
在 System.Windows.Forms.Control.OnMouseLeave(EventArgs e)
在 System.Windows.Forms.Control.WmMouseLeave(Message& m)
在 System.Windows.Forms.Control.WndProc(Message& m)
在 System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
在 System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
在 System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
...全文
208 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
於黾 2014-07-10
  • 打赏
  • 举报
回复
这是多线程同时调用静态函数造成的问题?
CGabriel 2014-07-10
  • 打赏
  • 举报
回复
引用 8 楼 lovetsfuer 的回复:
UI线程也做了处理,代码如下

   public static void SetText<TObject>(TObject objCtrl, string text, Form winf) where TObject : System.Windows.Forms.Control
        {
            if (objCtrl.InvokeRequired)
            {
                SetTextUI d = new SetTextUI(SetText);
                if (winf.IsDisposed)
                {
                    return;
                }
                winf.Invoke(d, new object[] { objCtrl, text, winf });
            }
            else
            {
                objCtrl.Text = text;
            }
        }
你的代码粗略看上去没有问题,但是感觉非常复杂,如果能够简化就好。 MSDN 上面有个例子,看能不能对你有帮助: How to: Make Thread-Safe Calls to Windows Forms Controls
lovetsfuer 2014-07-10
  • 打赏
  • 举报
回复
引用
除了主线程(也有人叫 UI 线程)之外,任何线程都不可以访问 UI 上面的东西,否则会有一定概率出错。这是 windows 的 消息泵机制决定的。 如果后台线程希望更新主线程,可以使用 control.Invoke or control.BeginInvoke 来实现。
UI线程也做了处理,代码如下

   public static void SetText<TObject>(TObject objCtrl, string text, Form winf) where TObject : System.Windows.Forms.Control
        {
            if (objCtrl.InvokeRequired)
            {
                SetTextUI d = new SetTextUI(SetText);
                if (winf.IsDisposed)
                {
                    return;
                }
                winf.Invoke(d, new object[] { objCtrl, text, winf });
            }
            else
            {
                objCtrl.Text = text;
            }
        }
CGabriel 2014-07-09
  • 打赏
  • 举报
回复
引用 4 楼 lovetsfuer 的回复:
[quote=引用 2 楼 wanghui0380 的回复:] 额,基本不是这个问题,虽然你非线程操作UI是有安全原因 但是你目前的报错信息OutOfMemoryException,内存溢出错,估计还是无限循环了 额ls红孩儿咋到处有你,但是每次回答滴时候,能不能好好看题目在回答啊
非UI线程是一直执行
引用 3 楼 Z65443344 的回复:
MyClass.ThreadUI.SetTxt(TXTValue1, "-" + num.ToString(), this); 这是交给了一个新的线程处理UI问题? 线程一直在开启,没有终止,导致内存不足?
如果thread2与UI线程这样操作基本上没异常,多个thread对一个UI,异常出现的还是多的,有时候系统莫名其妙闪退[/quote] 除了主线程(也有人叫 UI 线程)之外,任何线程都不可以访问 UI 上面的东西,否则会有一定概率出错。这是 windows 的 消息泵机制决定的。 如果后台线程希望更新主线程,可以使用 control.Invoke or control.BeginInvoke 来实现。
lovetsfuer 2014-07-09
  • 打赏
  • 举报
回复
附上UI线程

  /// <summary>
        /// 委托更改文本
        /// </summary>
        /// <param name="objCtrl"></param>
        /// <param name="text"></param>
        /// <param name="winf"></param>
        delegate void SetTextUI(System.Windows.Forms.Control objCtrl, string text, Form winf);
引用 5 楼 liqiucu 的回复:
UI线程(主线程) invoke 你的所有非UI线呈(写一个轮训),这样应该不会错了
考虑
liqiucu 2014-07-09
  • 打赏
  • 举报
回复
UI线程(主线程) invoke 你的所有非UI线呈(写一个轮训),这样应该不会错了
lovetsfuer 2014-07-09
  • 打赏
  • 举报
回复
引用 2 楼 wanghui0380 的回复:
额,基本不是这个问题,虽然你非线程操作UI是有安全原因 但是你目前的报错信息OutOfMemoryException,内存溢出错,估计还是无限循环了 额ls红孩儿咋到处有你,但是每次回答滴时候,能不能好好看题目在回答啊
非UI线程是一直执行
引用 3 楼 Z65443344 的回复:
MyClass.ThreadUI.SetTxt(TXTValue1, "-" + num.ToString(), this); 这是交给了一个新的线程处理UI问题? 线程一直在开启,没有终止,导致内存不足?
如果thread2与UI线程这样操作基本上没异常,多个thread对一个UI,异常出现的还是多的,有时候系统莫名其妙闪退
於黾 2014-07-09
  • 打赏
  • 举报
回复
MyClass.ThreadUI.SetTxt(TXTValue1, "-" + num.ToString(), this); 这是交给了一个新的线程处理UI问题? 线程一直在开启,没有终止,导致内存不足?
wanghui0380 2014-07-09
  • 打赏
  • 举报
回复
额,基本不是这个问题,虽然你非线程操作UI是有安全原因 但是你目前的报错信息OutOfMemoryException,内存溢出错,估计还是无限循环了 额ls红孩儿咋到处有你,但是每次回答滴时候,能不能好好看题目在回答啊
於黾 2014-07-09
  • 打赏
  • 举报
回复
搜索委托操作UI 跟多少没关系,只要是非UI线程对UI操作都会报错 解决办法就是将操作委托给UI线程去执行

110,546

社区成员

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

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

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