【高分求教】关于我不知道怎么描述的问题

heku518 2010-11-11 04:17:00
求教高手:实在不知道要把问题描述成如何?
有一个DataGridView控件
控件的列字段是静态创建的
总共有8列

程序运行的时候顺序是这样的,下面给出三个函数,很明显我要实现的是异步通信的方式
第一次运行程序的时候没有问题,
当我关掉重新运行该程序的时候,
也就是第二次我依然使用先前的套接字就会提示“不能向没有列的DataGridView控件添加行。”


重要的是我用红色字体标出的问题。。

public void StartListen()
{
if (MainForm.sockBindFlag.Equals(false))//套接字还未创建
{
.....
}
while (true)
{
allDone.Reset();
listenSoc.Soc.BeginAccept(new AsyncCallback(AcceptCallback), listenSoc);//接收请求
allDone.WaitOne();
}
}

public void AcceptCallback(IAsyncResult ar)
{
try
{
.......
.......
/*dataGridView1添加内容*/
string updateDataGridView = "SELECT RoomNo as 房间编号,RoomName as 房间名称,SocketNo as 套接字编号,";
updateDataGridView += "FloorName as 层名称,BulidName as 楼名称, AreaName as 区域名称,BrightNess as 房间亮度 from RoomCtrlView ";
updateDataGridView += "where IPAddress ='" + clientSoc[nSoc].RemoteUserName + "'";
DataSet ds = G_SqlExecute.GetDs(updateDataGridView, "Room");
UpdateRoomDataView(ds);
clientSoc[nSoc].ReceiveData();//接收消息
}
}
catch (SocketException se)
{
MessageBox.Show(se.Message + "AcceptCallback");
}
}

private void UpdateRoomDataView(DataSet ds)
{
int columnCount = 0;
columnCount = ds.Tables[0].Columns.Count;
object[] obj = new object[columnCount + 1];

if (ds.Tables[0].Rows.Count > 0)
{
for (int k = 0; k < ds.Tables[0].Rows.Count; k++)
{
obj[0] = 0;
for (int i = 1; i < columnCount; i++)
{
obj[i] = ds.Tables[0].Rows[k][i - 1].ToString();
}
obj[columnCount] = ds.Tables[0].Rows[k][columnCount - 1];
}
try
{
dataGridView1.Rows.Add(obj);//将每一行的值添加到DataGridView上
//在这我捕捉异常,提示“不能向没有列的DataGridView控件添加行。”
//可是我的列明明就是静态创建好的,这是为什么???? }
catch (Exception e)
{
MessageBox.Show(e.Message);
}
}
}

...全文
138 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
heku518 2010-11-12
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 sp1234 的回复:]
懒的看你的程序流程,我写消息服务程序从来不用同步阻塞。
[/Quote]
感谢你的提醒!我现在就试试真正的异步通信带来的神奇效果!
heku518 2010-11-12
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 sp1234 的回复:]
使用真正的异步编程吧,不要用同步阻塞(xxxx.WaitOne)来模拟异步。这种按照同步程序编写思路然后又阻塞的做法,你自己就乱了。

一个真正异步的程序,一旦执行了BeginAccept这时方法就结束了,而不会一直陷在在while循环里。

异步的程序编写起来非常简洁,而用同步阻塞来模拟异步的程序则很乱、代码很多。
[/Quote]
/// <summary>
/// 监听指定网络接口Ip的指定端口
/// </summary>
/// <param name="ipAddress">Ip地址</param>
/// <param name="port">端口号</param>
public void Begin(string ipAddress, int port)
{
socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

IPEndPoint end = new IPEndPoint(IPAddress.Parse(ipAddress), port);
socket.Bind(end);

//最大监听队列长度为100
socket.Listen(100);
//异步监听开始
socket.BeginAccept(new AsyncCallback(Accept), socket);
}

#endregion

#region 异步接收

/// <summary>
/// 异步接收数据
/// </summary>
/// <param name="ia"></param>
void Accept(IAsyncResult ia)
{
Socket soc = ia.AsyncState as Socket;

Socket worker = soc.EndAccept(ia);

soc.BeginAccept(new AsyncCallback(Accept), soc);

byte[] buf = new byte[1];
SocketHelper helper = new SocketHelper(buf, worker);

//异步读取数据
worker.BeginReceive(buf, 0, 1, SocketFlags.None, new AsyncCallback(Receive), helper);
}

是这个吗?这就是你说的简洁的异步通信??
heku518 2010-11-12
  • 打赏
  • 举报
回复
还是没有解决这个问题?有没有其他人碰到过这问题呢?
“不能向没有添加列的DataGridView”控件添加行,必须添加列!”
我的DataGridView控件是静态的,而且列也是静态添加好的。

private void UpdateRoomDataView(DataSet ds)
{
int columnCount = 0;
columnCount = ds.Tables[0].Columns.Count;
object[] obj = new object[columnCount + 1];

if (ds.Tables[0].Rows.Count > 0)
{
for (int k = 0; k < ds.Tables[0].Rows.Count; k++)
{
obj[0] = 0;
for (int i = 1; i < columnCount; i++)
{
obj[i] = ds.Tables[0].Rows[k][i - 1].ToString();
}
obj[columnCount] = ds.Tables[0].Rows[k][columnCount - 1];
}
try
{
dataGridView1.Rows.Add(obj);//将每一行的值添加到DataGridView上
//在这我捕捉异常,提示“不能向没有列的DataGridView控件添加行。”
//可是我的列明明就是静态创建好的,这是为什么???? }
catch (Exception e)
{
MessageBox.Show(e.Message);
}
}
}

上面这段代码到底是什么问题啊?
  • 打赏
  • 举报
回复
懒的看你的程序流程,我写消息服务程序从来不用同步阻塞。
  • 打赏
  • 举报
回复
使用真正的异步编程吧,不要用同步阻塞(xxxx.WaitOne)来模拟异步。这种按照同步程序编写思路然后又阻塞的做法,你自己就乱了。

一个真正异步的程序,一旦执行了BeginAccept这时方法就结束了,而不会一直陷在在while循环里。

异步的程序编写起来非常简洁,而用同步阻塞来模拟异步的程序则很乱、代码很多。
heku518 2010-11-11
  • 打赏
  • 举报
回复
我顶,100分都没人要接吗?
还是高手刚好都不在线上?
顶上去....
heku518 2010-11-11
  • 打赏
  • 举报
回复
对了提示那个错误的时候,
DataGridView这个控件其实是有那些列的!!!
之前我用动态创建列的时候,每次窗体创建都会去执行DataGridView控件列的动态创建。
现在换成静态创建列竟然还是提示那个错误...我要崩溃了~~
这一点很诡异....
明明有,却提示“不能向没有列的DataGridView控件添加行。”
zjskyooo 2010-11-11
  • 打赏
  • 举报
回复
新人 学习一下
heku518 2010-11-11
  • 打赏
  • 举报
回复
我一直怀疑是不是异步的问题》???
之前一次的套接字并没有soc.ShutDown然后soc.Close()
我第二次开启程序的时候,是直接使用原来绑定好的套接字。
代码如下:

private void McuControl_FormClosed(object sender, FormClosedEventArgs e)
{
if (serverThread != null)
{
if (serverThread.IsAlive)
{
if (listenSoc.Soc.Connected)//从这里开始一直都没有执行到里面
{
listenSoc.Soc.Shutdown(SocketShutdown.Both);//所以套接字关闭不了使得我不得不继续使用这个套接字,而没办法重新创建一个新的套接字!
listenSoc.Soc.Close();
}
serverThread.Abort();
}
}
}
heku518 2010-11-11
  • 打赏
  • 举报
回复
查了一下,只有一处,不过是要点击按钮才会实现DataGridView的Clear方法。
高手再帮我想想哈!
三岁、就很帅 2010-11-11
  • 打赏
  • 举报
回复
帮顶 接分
兔子-顾问 2010-11-11
  • 打赏
  • 举报
回复
检查下是不是哪里执行了DataGridView的Clear方法。
heku518 2010-11-11
  • 打赏
  • 举报
回复
我的问题:提示“不能向没有列的DataGridView控件添加行。”
也有可能是关于异步通信的问题!!!不知道怎么会这样?

111,129

社区成员

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

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

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