在 System.InvalidOperationException 中第一次偶然出现的“System.Windows.Forms.dll”类型的异常

oioixiabings 2010-05-01 09:34:19
本人在学习C#过程中试着实践做一个USB电话盒的二次开发.
厂家提供电话盒的DLL,并提供说明.

编写的思路是:先利用回调函数调用DLL中的打开设备函数,再利用回调函数实现对USB电话盒的各类事件作出响应.

回调和事件响应都已成功,但想在事件响应中对Form1窗口中的控件外观进行控制,运行没问题,但在输出窗口中出现"在 System.InvalidOperationException 中第一次偶然出现的“System.Windows.Forms.dll”类型的异常",Textbox1中的内容无改变.


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;

namespace USBtelephone
{
public partial class Form1 : Form
{
UsbBox myUsBox = new UsbBox();
public Form1()
{
InitializeComponent();
}
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
myUsBox.Close();
}
private void Form1_Load(object sender, EventArgs e)
{
UboxEventsubscribe();//USB电话盒的各类事件订阅

}
private void UboxEventsubscribe()//USB电话盒的各类事件订阅
{
myUsBox.TelephoneOffLine += new EventHandler(myUsBox_TelephoneOffLine);//订阅摘机事件
myUsBox.TelelphoneShutDown+=new EventHandler(myUsBox_TelelphoneShutDown);//订阅挂机事件
}
void myUsBox_TelephoneOffLine(object sender, EventArgs e)
{
Debug.WriteLine("电话机摘机了(In Form)");

}

private void myUsBox_TelelphoneShutDown(object sender, EventArgs e)//响应电话机挂机事件
{
Debug.WriteLine("挂机了(in Form)");
this.textBox1.Text = "HI,HI!";
}

private void Form1_Activated(object sender, EventArgs e)
{
myUsBox.Open();

}

}

}

以下是UsbBox 类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;//这句一定要
using System.Diagnostics;

namespace USBtelephone
{
class UsbBox
{
#region 定义枚举类型UBOX_EVENT_Enum
enum UBOX_EVENT_Enum
{
UBOX_EVENT_LINE_RINGING = 11, //振铃,硬件LED亮
UBOX_EVENT_LINE_HOOK_OFF = 12, //摘机,硬件LED亮
UBOX_EVENT_RING_CANCEL = 15, //振铃取消,当末次振铃停止超过6秒,则触发此事件,
UBOX_EVENT_LINE_HOOK_UP = 30, //挂机
}//end UBOX_EVENT_Enum
#endregion

private int UsbBoxHwnd;//设备名柄

#region 各类事件定义
public event EventHandler LineRing;//线路振铃事件
public event EventHandler RING_CANCEL;//振铃取消,当末次振铃停止超过6秒,则触发此事件

public event EventHandler TelelphoneShutDown;//挂机事件
public event EventHandler TelephoneOffLine;//摘机事件
#endregion

#region Dll各类命令定义
//Dll各类命令定义
//------------------------------------------------------------------------------------------------
[DllImport(@"E:\UsbTel\phonic_ubox.dll")]
static extern int ubox_open(UBoxEventNotifyProc proc, int mode);//UBoxEventNotifyProc回调函数

[DllImport(@"E:\UsbTel\phonic_ubox.dll")]
static extern void ubox_close();

[DllImport(@"E:\UsbTel\phonic_ubox.dll")]
static extern int ubox_get_work_mode();

[DllImport(@"E:\UsbTel\phonic_ubox.dll")]
static extern int ubox_send_dtmf(int uboxHnd, string dmftfstring);
//---------------------------------------------------------------------------------------------
#endregion


//定义Usb电话盒的二次开发包的回调函数委托
public delegate void UBoxEventNotifyProc(int uboxHnd, int eventID, uint param1, uint param2, uint param3, uint param4);//param1~parm4代表各类返回值

#region usb电话盒回调函数
//usb电话盒回调函数
unsafe private void Ubox_Event_CallBack(
int uboxHnd, int eventID, uint param1,
uint param2, uint param3, uint param4)//USB盒回调函数
{
EventArgs e = new EventArgs();
UBOX_EVENT_Enum myUboxEven = (UBOX_EVENT_Enum)eventID;
switch (myUboxEven)//对回调的eventID值产生各类事件
{

case UBOX_EVENT_Enum.UBOX_EVENT_LINE_RINGING://=11振铃
if (LineRing != null) LineRing(this, e);//发出振铃事件
break;

case UBOX_EVENT_Enum.UBOX_EVENT_RING_CANCEL://=15 振铃取消,当末次振铃停止超过6秒触发此事件
if (RING_CANCEL != null) RING_CANCEL(this, e);//发出振铃取消事件
break;

case UBOX_EVENT_Enum.UBOX_EVENT_LINE_HOOK_UP://挂机
if (TelelphoneShutDown != null) TelelphoneShutDown(this, e);//发出挂机事件
break;

case UBOX_EVENT_Enum.UBOX_EVENT_LINE_HOOK_OFF://摘机
if (TelephoneOffLine != null) TelephoneOffLine(this, e);//发出摘机事件
break;
}
}//end Ubox_Event_CallBack
#endregion

public void Open()
{
UBoxEventNotifyProc myUBoxEvNoProc = new UBoxEventNotifyProc(Ubox_Event_CallBack);//定义委托变量

int resultOpen = ubox_open(myUBoxEvNoProc, 0);//打开设备,并付予委托
Debug.WriteLine(string.Format("Open result={0}", resultOpen));
}//end Open

public void Close()
{
ubox_close();
}

}//end class Usbbox
}

是不是有交叉线程调用问题,请高手指教,谢谢!
...全文
2947 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
xingyuebuyu 2010-05-01
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 computerfox 的回复:]
没有看到你这里有跨线程访问呀,如果是跨线程访问,请参考这个帖子吧:
http://topic.csdn.net/u/20100428/14/78736388-bb69-4c2d-8a1d-11df04a5d0f0.html
[/Quote]

使用委托对this.textBox1赋值,可能回调函数Ubox_Event_CallBack是在DLL中新建的一个线程中运行的.
oioixiabings 2010-05-01
  • 打赏
  • 举报
回复
异常出现在这一句:this.textBox1.Text = "HI,HI!";
oioixiabings 2010-05-01
  • 打赏
  • 举报
回复
异常出现在这一名:this.textBox1.Text = "HI,HI!";
捷哥1999 2010-05-01
  • 打赏
  • 举报
回复
没有看到你这里有跨线程访问呀,如果是跨线程访问,请参考这个帖子吧:
http://topic.csdn.net/u/20100428/14/78736388-bb69-4c2d-8a1d-11df04a5d0f0.html
oioixiabings 2010-05-01
  • 打赏
  • 举报
回复
问题已解决:
如5楼所说,DLL中存在线程,必需安全调用窗体控件,具体参考(对 Windows 窗体控件进行线程安全调用):
http://msdn.microsoft.com/zh-cn/library/ms171728%28VS.80%29.aspx

110,536

社区成员

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

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

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