I have two threads that are declared global.On the form load i start the two threads.On the exit button click i am trying to abort these two threads if they are alive or else join.But i get this error “Attempted to read write protected memory” and the applications hangs sometimes.In one thread i am creating a pipe and waiting for connection in a while loop and in the other thread i am updating a datagrid on the background form.
Any ideas what is happening.I can post the code if my question is not clear enough but the code is very big.
Thanks
The code for form load is
private void frmStatus_Load(object sender, EventArgs e)
{
Control.CheckForIllegalCrossThreadCalls = false;
RefreshStatus = new Thread(RefreshStatusForm);
RefreshStatus.IsBackground = true;
RefreshStatus.Start();
th = new Thread(this.CreatePipe);
th.IsBackground = true;
th.Start();
}
The code for closing the form is on a button click
private void btnOk_Click(object sender, EventArgs e)
{
try
{
System.Object lockThis = new System.Object();
lock (lockThis)
{
bCheckVal = false;
if (!this.bComplete)
stopOperation();
Thread.Sleep(1000);
////////These are the lines in which i get the error
if (!th.IsAlive)
{
th.Join();
}
else
{
th.Abort();
}
this.bRefresh = false;
Thread.Sleep(1000);
if (RefreshStatus.IsAlive)
RefreshStatus.Abort();
else
RefreshStatus.Join();
/////////////////
this.bFlag = true;
}
this.Close();
}
catch (System.Exception ex)
{
}
}
The code which is executed by the threads
public void CreatePipe()
{
try
{
PipeSecurity pipeSa = new PipeSecurity();
pipeSa.SetAccessRule(new PipeAccessRule("Everyone",
PipeAccessRights.ReadWrite, AccessControlType.Allow));
NamedPipeServerStream pipeServer = new NamedPipeServerStream(
this.strguid, // The unique pipe name.
PipeDirection.InOut, // The pipe is bi-directional
NamedPipeServerStream.MaxAllowedServerInstances);
string strMessage = string.Empty;
char[] bRequest = new char[BUFFER_SIZE];// Client -> Server
int cbBytesRead, cbRequestBytes;
StreamReader sr = null;
byte[] bReply; // Server -> Client
int cbBytesWritten, cbReplyBytes;
int icount = 0;
List<string> lsRead = new List<string>();
cbBytesRead = 0;
CopyFileThread = new Thread(this.CopyFile);
CopyFileThread.IsBackground = true;
CopyFileThread.Start();
bool bflag = false;
while (true)
{
this.bComplete = false;
bWait = true;
try
{
pipeServer.WaitForConnection();
sr = new StreamReader(pipeServer);
//string message = sr.ReadToEnd();
bWait = false;
cbRequestBytes = BUFFER_SIZE;
string pipeData = string.Empty;
pipeData = sr.Read(bRequest, 0, 255).ToString().Trim();
strMessage = new string(bRequest);
strMessage = strMessage.Replace("\0", string.Empty);
if (strMessage.Contains("Aborted"))
{
if (pipeServer.IsConnected)
{
pipeServer.Flush();
pipeServer.Disconnect();
}
break;
}
else
if (strMessage.Contains("Completed"))
{
if (progressBar1.InvokeRequired)
{
strPercent = "100%";
}
if (pipeServer.IsConnected)
{
pipeServer.Flush();
pipeServer.Disconnect();
}
this.bComplete = true;
break;
}
// 26 dec 2011 Comment code //////
if (strMessage == "")
{
progressBar1.Visible = false;
progressBar2.Visible = true;
}
else
{
progressBar1.Visible = true;
progressBar2.Visible = false;
}
//// 26 dec 2011 Comment code //////
string[] strStatusMessages = strMessage.Trim().Split(',');
// 26 dec 2011 Comment code //////
pipeServer.Flush();
pipeServer.Disconnect();
}
catch (System.Exception ex)
{
//MessageBox.Show(ex.ToString());
}
}
pipeServer.Close();
if (CopyFileThread.IsAlive)
CopyFileThread.Abort();
else
CopyFileThread.Join();
MessageBox.Show("Exiting from createpipe 2 Thread :{0}", Thread.CurrentThread.ToString());
return;
}
catch (Exception ex)
{
return;
}
}
//////////////////////////////
void RefreshStatusForm()
{
while (bRefresh)
{
if (iRefresh == 1)
{
GetRefresh();
iRefresh = 0;
}
else if (iRefresh == 2)
break;
Thread.Sleep(1000);
}
MessageBox.Show("Exiting from RefreshStatusForm 2 Thread :{0}", Thread.CurrentThread.ToString());
}
You don’t need to abort or join the thread. It is better to just let them finish normally. In your thread that does “waiting for connection in a while loop” have the while loop condition set as a bool and when you exit the program set the bool to false. Do something similar with the other thread as well.
EDIT1
So first of all:
instead should be something like
You use
which is going to block the thread so I would change it an async task
but if you do not want to do that then add a timeout every so often.
Then in
all you need to do is set
then the threads will finish themselves.
EDIT2
Set it up by using:
Add this method:
Now when a connection occurs AsyncPipeCallback is called. Then when it finishes it check to see if it is still Running if it is it BeginWaitForConnection again.
In btnOk_Click change it to this: