串口通信中,受到,发送的数据都被写入到了每天的日志文件中。
但是偶尔也,会出现,如下的提示。
An unhandled exception of type “system.IO.IOException” occurred in mscorlib.dll.
Additional information: The process cannot access the file “c:\mydata\20080715-MSG.log” because it is used by another process.我搞不清楚日志文件,为何会被多个进程访问。日志写入的代码如下
public static void LogFile(string comment)
{
string filename = Application.StartupPath + "\\" + global.SystemInfo_LogName() + "-MSG.Log";
StreamWriter sw = new StreamWriter(filename, true);
sw.WriteLine(comment);
sw.Close();
}//通过串口发信的时候
public static void LogSendFile(string strSendAscii, DateTime dt)
{
//
//DateTime dt = DateTime.Now;
int i;
string strTime = string.Format("{0:d2}:{1:d2}:{2:d2}", dt.Hour, dt.Minute, dt.Second);
string strDateTime = string.Format("{0} {1} {2:d3}", dt.ToShortDateString(), strTime, dt.Millisecond);
string strHex = "";
for (i = 0; i < strSendAscii.Length; i++)
{
string t = strSendAscii.Substring(i, 1).ToString();
short xxx = global.CSharpASC(t);
string tt = "0" + xxx.ToString("X");
strHex += "-" + tt.Substring(tt.Length - 2, 2);
} string strTemp = strDateTime + ",H->R:Recv" + strSendAscii + "\r\n";
string strLogText = strDateTime + " " + strHex + " " + strSendAscii;
LogFile(strLogText);
}
//通过串口受信的时候
public static void LogRecvFile(string strReceiveAscii, DateTime dt)
{
//
int i;
string strTime = string.Format("{0:d2}:{1:d2}:{2:d2}", dt.Hour, dt.Minute, dt.Second);
string strDateTime = string.Format("{0} {1} {2:d3}", dt.ToShortDateString(), strTime, dt.Millisecond);
string strHex = "";
for (i = 0; i < strReceiveAscii.Length; i++)
{
string t = strReceiveAscii.Substring(i, 1).ToString();
short xxx = global.CSharpASC(t);
string tt = "0" + xxx.ToString("X");
strHex += "-" + tt.Substring(tt.Length - 2, 2);
} string strTemp = strDateTime + ",H->R:Recv" + strReceiveAscii + "\r\n";
string strLogText = strDateTime + " " + strHex + " " + strReceiveAscii;
LogFile(strLogText);
}
主程序是通过收发串口的命令,来控制机器人动作的。
机器人的主要有,回到初始位置,取,放
Main()中有一个大的while()来处理机器人动作的循环。 //如果命令缓冲区中,有让机器人回到初始位置的命令
while (global.CmdSequenceCheck("ORIG") && !end_flg)
{
Application.DoEvents();
//如果通过WaitPrimaryOrigMsg()得到了让机器人回到初始位置的命令
if (global.OrigStepState == 0 && global.WaitPrimaryOrigMsg())
global.OrigStepState = 1; //那么机器人的状态切换 if (global.OrigStepState == 1)
{ //那么机器人就回答说,我知道了,通过串口送回去
string strSend = global.EchoAutoAnswerOrig(true, "00", "00");
SendMsg(strSend);// 通过串口送回去
global.OrigStepState = 2; //然后机器人的状态切换
}
//rebot ORIG動作
//然后,机器人执行回到初始位置的动作
if (global.OrigStepState == 2)
{
timerGap.Interval = 15000;
timerGap.Start();
do
{
Application.DoEvents();
Thread.Sleep(1);
} while (timerGap.Enabled);
mapRobot.bOrigPoint = true;
global.OrigStepState = 3;//状態管理
}
if (global.OrigStepState == 3)
{//机器人回到原点后,告诉服务器,说,我已经回到原点了。
string strSendTemp = global.PrimaryEvt1Send(true,
strSeq, global._ReceiveCommand._shaft,
strLArmErrorCode, strMArmErrorCode, strHArmErrorCode,
strHand1ST, strHand2nd);
SendMsg(strSendTemp);
global.OrigStepState = 4;//那么状态前进
}
//Waiting host answer...
//之后,机器人等待服务器说----我已经知道你回到原点了
//机器人是通过WaitEchoEvt1OrigMsg()来得知服务器的回答消息的
if (global.OrigStepState == 4 && global.WaitEchoEvt1OrigMsg())
{ //状態回復
global.OrigStepState = 0;
global.CmdSequenceAdminDelete("ORIG");
//之后,收信缓冲区之中的orig清除,
//以便于处理其他的命令
}
//那么可以看出,一共需要4步的交互动作。
//需要不停的把串口的消息,写入到日志文件
}// orig while end While(){
//Get 的命令处理,取物品
//诸多的命令,都类似于上面,都是采用一问一答的方式,
//而且是很多步的交互动作
//get动作需要12步左右
}
While(){
//put 的命令处理,放物品
}
}//处理整个动作命令的while循环,
1.我自己想,不可能再有其他程序来访问日志文件,只有我自己的程序访问日志文件。
2.这是不是由于程序中使用了大量的 Application.DoEvents();造成什么异步访问,我对此也不明白。
3.对于我自己的程序中,多个进程同时访问日志,造成失败的原因,我不清楚。希望能得到大家的指点。
4.如何控制,或者避免,多个进程同时访问一个文件呢?这些预防的方法,请大家告诉我好吗?
我自己对于硬件的控制程序,经验不多。在调试时候发现,由于使用了DoEvent()后,程序就变得混乱不堪了。
不是按照线性的方式执行,跳来跳去,代码也是并行的执行的。-----当然这是由于DoEvent()的特性造成的,这个我明白的。
但是为什么,会造成多个进程来同时访问日志文件呢?是不是由于DoEvent()后,程序不是按照线性方式执行,而造成的呢?
谢谢大家。敬礼!
还有,上面的代码中 timerGap 定时器,采用的是System.Timers.Timer定时器,据说,可以处理多线程。
public static System.Timers.Timer timerGap = new System.Timers.Timer();
在此再次谢谢各位。
但是偶尔也,会出现,如下的提示。
An unhandled exception of type “system.IO.IOException” occurred in mscorlib.dll.
Additional information: The process cannot access the file “c:\mydata\20080715-MSG.log” because it is used by another process.我搞不清楚日志文件,为何会被多个进程访问。日志写入的代码如下
public static void LogFile(string comment)
{
string filename = Application.StartupPath + "\\" + global.SystemInfo_LogName() + "-MSG.Log";
StreamWriter sw = new StreamWriter(filename, true);
sw.WriteLine(comment);
sw.Close();
}//通过串口发信的时候
public static void LogSendFile(string strSendAscii, DateTime dt)
{
//
//DateTime dt = DateTime.Now;
int i;
string strTime = string.Format("{0:d2}:{1:d2}:{2:d2}", dt.Hour, dt.Minute, dt.Second);
string strDateTime = string.Format("{0} {1} {2:d3}", dt.ToShortDateString(), strTime, dt.Millisecond);
string strHex = "";
for (i = 0; i < strSendAscii.Length; i++)
{
string t = strSendAscii.Substring(i, 1).ToString();
short xxx = global.CSharpASC(t);
string tt = "0" + xxx.ToString("X");
strHex += "-" + tt.Substring(tt.Length - 2, 2);
} string strTemp = strDateTime + ",H->R:Recv" + strSendAscii + "\r\n";
string strLogText = strDateTime + " " + strHex + " " + strSendAscii;
LogFile(strLogText);
}
//通过串口受信的时候
public static void LogRecvFile(string strReceiveAscii, DateTime dt)
{
//
int i;
string strTime = string.Format("{0:d2}:{1:d2}:{2:d2}", dt.Hour, dt.Minute, dt.Second);
string strDateTime = string.Format("{0} {1} {2:d3}", dt.ToShortDateString(), strTime, dt.Millisecond);
string strHex = "";
for (i = 0; i < strReceiveAscii.Length; i++)
{
string t = strReceiveAscii.Substring(i, 1).ToString();
short xxx = global.CSharpASC(t);
string tt = "0" + xxx.ToString("X");
strHex += "-" + tt.Substring(tt.Length - 2, 2);
} string strTemp = strDateTime + ",H->R:Recv" + strReceiveAscii + "\r\n";
string strLogText = strDateTime + " " + strHex + " " + strReceiveAscii;
LogFile(strLogText);
}
主程序是通过收发串口的命令,来控制机器人动作的。
机器人的主要有,回到初始位置,取,放
Main()中有一个大的while()来处理机器人动作的循环。 //如果命令缓冲区中,有让机器人回到初始位置的命令
while (global.CmdSequenceCheck("ORIG") && !end_flg)
{
Application.DoEvents();
//如果通过WaitPrimaryOrigMsg()得到了让机器人回到初始位置的命令
if (global.OrigStepState == 0 && global.WaitPrimaryOrigMsg())
global.OrigStepState = 1; //那么机器人的状态切换 if (global.OrigStepState == 1)
{ //那么机器人就回答说,我知道了,通过串口送回去
string strSend = global.EchoAutoAnswerOrig(true, "00", "00");
SendMsg(strSend);// 通过串口送回去
global.OrigStepState = 2; //然后机器人的状态切换
}
//rebot ORIG動作
//然后,机器人执行回到初始位置的动作
if (global.OrigStepState == 2)
{
timerGap.Interval = 15000;
timerGap.Start();
do
{
Application.DoEvents();
Thread.Sleep(1);
} while (timerGap.Enabled);
mapRobot.bOrigPoint = true;
global.OrigStepState = 3;//状態管理
}
if (global.OrigStepState == 3)
{//机器人回到原点后,告诉服务器,说,我已经回到原点了。
string strSendTemp = global.PrimaryEvt1Send(true,
strSeq, global._ReceiveCommand._shaft,
strLArmErrorCode, strMArmErrorCode, strHArmErrorCode,
strHand1ST, strHand2nd);
SendMsg(strSendTemp);
global.OrigStepState = 4;//那么状态前进
}
//Waiting host answer...
//之后,机器人等待服务器说----我已经知道你回到原点了
//机器人是通过WaitEchoEvt1OrigMsg()来得知服务器的回答消息的
if (global.OrigStepState == 4 && global.WaitEchoEvt1OrigMsg())
{ //状態回復
global.OrigStepState = 0;
global.CmdSequenceAdminDelete("ORIG");
//之后,收信缓冲区之中的orig清除,
//以便于处理其他的命令
}
//那么可以看出,一共需要4步的交互动作。
//需要不停的把串口的消息,写入到日志文件
}// orig while end While(){
//Get 的命令处理,取物品
//诸多的命令,都类似于上面,都是采用一问一答的方式,
//而且是很多步的交互动作
//get动作需要12步左右
}
While(){
//put 的命令处理,放物品
}
}//处理整个动作命令的while循环,
1.我自己想,不可能再有其他程序来访问日志文件,只有我自己的程序访问日志文件。
2.这是不是由于程序中使用了大量的 Application.DoEvents();造成什么异步访问,我对此也不明白。
3.对于我自己的程序中,多个进程同时访问日志,造成失败的原因,我不清楚。希望能得到大家的指点。
4.如何控制,或者避免,多个进程同时访问一个文件呢?这些预防的方法,请大家告诉我好吗?
我自己对于硬件的控制程序,经验不多。在调试时候发现,由于使用了DoEvent()后,程序就变得混乱不堪了。
不是按照线性的方式执行,跳来跳去,代码也是并行的执行的。-----当然这是由于DoEvent()的特性造成的,这个我明白的。
但是为什么,会造成多个进程来同时访问日志文件呢?是不是由于DoEvent()后,程序不是按照线性方式执行,而造成的呢?
谢谢大家。敬礼!
还有,上面的代码中 timerGap 定时器,采用的是System.Timers.Timer定时器,据说,可以处理多线程。
public static System.Timers.Timer timerGap = new System.Timers.Timer();
在此再次谢谢各位。
{
lock(类名)
{
string filename = Application.StartupPath + "\\" + global.SystemInfo_LogName() + "-MSG.Log";
StreamWriter sw = new StreamWriter(filename, true);
sw.WriteLine(comment);
sw.Close();
}
}
加个锁lock试试!!!