编程是一项思维要求非常慎密的工作,一点也马虎不得。不可以忽略任何错误的可能。
对于很久之前的代码和别人的代码,可能存在理解错误的情况:
逻辑复杂,
注释错误、不充分,
变量函数命名误导,
代码冗余、补丁加补丁,
堆栈层次过多,
函数变量过多,
业务太复杂等等
我们一时不一定能看懂,甚至说理解错误,可能遇到万万不可自以为是。
如果一个函数或者变量的命名不能明确表明它的作用和含义,或者它具有多含义,多功能,跨文件和领域等等情况,顾名思义的认为它是什么样的,那就错了。
这些情境下,如果轻易的下结论,动手修改,可能造成不可预期的后果。
下面是早之前使用c#时候的编程日志和代码,时间在2008年的时候,把第三方函数(WriteBufToSocket)错认为是同步操作,从而造成接收数据丢失。即便是有补充操作,结果依然不符合预期。
使用别人的函数,而没有理解它的原理,才导致这样的乌龙。
实时发送
private void SendMsg(PocketHandle oinfo)
{
byte[] msg = oinfo.m_bufferPocket;
SendMsg(oinfo.m_nType, msg);
}
public void SendMsg(int nType, byte[] msg)
{
//byte[] msg = oinfo.m_bufferPocket;
bool bSucc = CommunClass.WriteBufToSocket(m_sock, msg, 0, msg.Length, msg.Length, OnSend);//里面使用了异步操作
if (!bSucc)
{
bool bsucc = SetSocket("", 0);
if (!bsucc)
bsucc = SetSocket(m_ip, m_port);
if (bsucc)
bSucc = CommunClass.WriteBufToSocket(m_sock, msg, 0, msg.Length, msg.Length, OnSend);
}
if (!bSucc)
{
SqlParameter[] paramters ={
new SqlParameter("@Type",SqlDbType.Int,4),
new SqlParameter("@SendStatus",SqlDbType.Int,4),
new SqlParameter("@Message",SqlDbType.VarBinary,msg.Length)
};
paramters[0].Value = nType;
paramters[1].Value = 0;
paramters[2].Value = msg;
int rowsAffected;
DbHelperSQL.RunProcedure("InsertUnSendInfo", paramters, out rowsAffected);//发送失败放到队列里
if (rowsAffected <= 0)
{
System.Diagnostics.Debug.Assert(true, "数据库操作失败");
}
}
//byte[] msg = Encoding.UTF8.GetBytes("43010010200806130008");
//m_sock.Send(msg);
}
对发送失败的数据定时做一次重发。
这也是个熟识的改造————把一个小的流程看作一个任务,然后在线程中排队处理。
这里面似乎少了锁定操作,不过也不必了,交给数据库处理吧。
protected void SendData()
{
//senddata
while (true)
{
Thread.Sleep(10000);
try
{
DataSet odsMsg = DbHelperSQL.Query("select ID, Type,SendStatus,Message from UnSendCommInfo");
int nCount = odsMsg.Tables[0].Rows.Count;//查询未发送的消息
int nID;
int nType;
byte[] sMessage;
for (int i = 0; i < nCount; i++)
{
bool bsucc = m_MessageHandle.SetSocket("", 0);//判断是否连接成功
if (!bsucc)
{
bsucc = m_MessageHandle.SetSocket(m_strIP, int.Parse(m_strPort));
if (!bsucc) break;
}
nType = int.Parse(odsMsg.Tables[0].Rows[i]["Type"].ToString());
nID = int.Parse(odsMsg.Tables[0].Rows[i]["ID"].ToString());
sMessage = (byte[])(odsMsg.Tables[0].Rows[i]["Message"]);
m_MessageHandle.SendMsg(nType, sMessage);//发送出去
int bS = DbHelperSQL.ExecuteSql("delete from unsendcomminfo where id=" + nID + " ");//然后从容器中删除
if (bS < 0)
{
System.Diagnostics.Debug.Assert(true, "数据库操作失败");
}
}
}
catch (Exception err)
{
System.Diagnostics.Debug.Assert(true, err.Message);
continue;
//throw;
}
}
}