I have method PatchUpdates which calls CheckConnection method to check the connection to remote pc if true then it will get back to first method to user interface and do some other stuff
I searched and found that I need to use threading so I am creating new thread
but my application hung and stops and nothing happen
please what I have done incorrect ?
thanks
public void PatchUpdates()
{
try
{
foreach (DataGridViewRow OfficeListRow in DGV_OfficeList.Rows)
{
string vIPAddress;
string vSoruceFilePath;
int RowNum;
foreach (DataGridViewRow FileListRow in DGV_FileList.Rows)
{
Thread thrd = new Thread(new System.Threading.ThreadStart(PatchUpdates));
thrd.Start();
vIPAddress = OfficeListRow.Cells[1].Value.ToString();
vSoruceFilePath = FileListRow.Cells[4].Value.ToString();
RowNum = OfficeListRow.Index;
///Check the connection to pc
if (CheckConnection(vIPAddress) == true)
{
//MessageBox.Show(vIPAddress + " Pingable ");
DGV_OfficeList[2, RowNum].Value = "Online";
OfficeListRow.DefaultCellStyle.BackColor = Color.LightGreen;
}
else
{
//MessageBox.Show(vIPAddress + " Not Pingable ");
DGV_OfficeList[2, RowNum].Value = "Offline";
OfficeListRow.DefaultCellStyle.BackColor = Color.LightCyan;
}
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Error Message", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
public static bool CheckConnection(string IPAddress)
{
bool vPingable = false;
try
{
Ping png = new Ping();
PingReply PngReply = png.Send(IPAddress);
vPingable = PngReply.Status == IPStatus.Success;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}
return vPingable;
}
You are passing PatchUpdates to the ThreadStart delegate from within the PatchUpdates() method.
Thread thrd = new Thread(new System.Threading.ThreadStart(PatchUpdates));
thrd.Start();
This means that PatchUpdates() method starts itself over again on a new second thread, where it will start itself over again on a new third thread, where it will start itself over again on a new fourth thread, an so on...
Basically you are starting infinite new threads (as long as there are items in DGV_FileList.Rows), which will consume all your resources eventually.
Related
I have a socket thread that blocks on read. I set the receivetimeout on the socket to 30 seconds; if no byte is read, the read goes into IO exception(inner exception: error code: 10060). I end the process and close the streams and set the thread to null. For some reason, I can't seem to close the socket connection. I am not sure where the error is. Below is my code:
public class SampleClientSocket
{
private Socket cltSocket = null;
private volatile bool readyToRecv = false;
NetworkStream ns;
BinaryReader br;
BinaryWriter wr;
private string _caller = "SampleSocketClient";
Thread workerThread;
static void Main(string[] args)
{
BeginWork();
}
public void BeginWork()
{
try
{
IPEndPoint ipe = new IPEndPoint("127.0.0.1", 5000);
cltSocket = new Socket(ipe.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
cltSocket.Connect(ipe);
cltSocket.ReceiveTimeout = 30000;
cltSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
workerThread = new Thread(doWork_01);
workerThread.Start();
readyToRecv = true;
}
catch (Exception f)
{
Console.WriteLine(this._caller + f.StackTrace);
}
}
private void doWork_01()
{
try
{
this.ns = new NetworkStream(this.cltSocket);
this.br = new BinaryReader(this.ns);
this.wr = new BinaryWriter(this.ns);
readyToRecv = true;
this._lastSocketRead = toUnixTime(DateTime.Now);
}
catch
{
Console.WriteLine(this._caller + "ERROR OPENING STREAMS.");
readyToRecv = false;
}
while (this.readyToRecv)
{
bool _etxEncountered = false;
MemoryStream currentMessage = new MemoryStream();
byte buf = (byte)0;
while (!_etxEncountered)
{
try
{
buf = this.br.ReadByte();
}
catch (EndOfStreamException)
{
Console.WriteLine(this._caller + "ERROR: END OF STREAM");
readyToRecv = false;
_etxEncountered = true;
break;
}
catch (ObjectDisposedException)
{
Console.WriteLine(this._caller + "ERROR: Stream is closed!");
readyToRecv = false;
_etxEncountered = true;
break;
}
catch (IOException i)
{
Console.WriteLine(this._caller + "ERRORSTACK: IOException!" + i.StackTrace);
//if the ReeceiveTimeout is reached an IOException will be raised...
/// with an InnerException of type SocketException an ErrorCode 10060
var socketExpert = i.InnerException as SocketException;
if (socketExpert.ErrorCode != 10060)
{
Console.WriteLine(this._caller + "ERROR: IOException!" + socketExpert.ErrorCode);
readyToRecv = false;
_etxEncountered = true;
}
else
{
Console.WriteLine(this._caller + "Read: IOException for timeout! NOT DISCONNECTING");
readyToRecv = false;
_etxEncountered = true;
break;
}
}
catch (Exception f)
{
Console.WriteLine(this._caller + "Unknown exception" + f.StackTrace);
var socketExpert = f.InnerException as SocketException;
Console.WriteLine(this._caller + "Error code number: " + socketExpert.ErrorCode);
readyToRecv = false;
_etxEncountered = true;
}
if (buf.Equals(0x03) == true)
{
_etxEncountered = true;
break;
}
else if (buf.Equals(0x02) == false)
{
try
{
currentMessage.WriteByte(buf);
}
catch (Exception)
{
}
}
}
try { Thread.Sleep(10); }
catch { }
} // end while
EndWork();
}
public void EndWork()
{
try
{
readyToRecv = false;
//close streams
this.br.BaseStream.Flush();
this.br.Close();
this.br.Dispose();
this.wr.Flush();
this.wr.Close();
this.wr.Dispose();
this.ns.Flush();
this.ns.Close();
this.ns.Dispose();
this.cltSocket.Shutdown(SocketShutdown.Both);
//this.cltSocket.Disconnect(true);
this.cltSocket.Close();
this.cltSocket.Dispose();
this.cltSocket = null;
Console.WriteLine(this._caller + "GOODBYE...");
try
{
this.workerThread.Join(1000);
if (this.workerThread.IsAlive)
{
this.workerThread.Abort();
}
}
catch { }
this.workerThread = null;
}
catch
{
this.readyToRecv = false;
this.workerThread = null;
}
return;
}
}
Any help is appreciated.
There seem to be numerous problems with this code.
I think the reason for the problems is that you are trying to join the worker thread on the worker thread. doWork_01 is run on a worker thread, and therefore EndWork will also run on the worker thread. this would be equivalent to calling Thread.CurrentThread.Join(), and will just deadlock. This deadlock will probably keep your process alive and might cause issues like not releasing the socket.
I see little reason for trying to use multiple threads here. The original thread just starts the worker and does nothing else. I would recommend removing all threading and just use local variables for the socket, and use using to ensure it is disposed.
To properly exit the process, use Environment.Exit(0);, Application.Exit or just return from Main.
I had a thread that wasn't hitting the Socket.Shutdown and socket.close. Thank you jdweng for pointing this to me.
I have 2 Methods, One method call the other. thread is declared inside the 2nd method and that method will return a boolean output. so when i call the 2nd method i cant control the output, and 1st method returns the success message before the thread ends. I want the boolean output after when the thread ends. How can i control this?
1st Method
private void AccessElements()
{
TaxoProcess Taxo = new TaxoProcess();
if (Taxo.AccessEntity())
{
MessageBox.Show("Succesfully Extracted Data", "Extract Application", MessageBoxButton.OK, MessageBoxImage.Information);
}
}
2nd Method,
public bool AccessEntity()
{
try
{
bool Status = true;
Thread MainThread = Thread.CurrentThread;
Thread backgroundThread = new Thread(new ThreadStart(() =>
{
for (int i = 0; i < Entities.Count; i++)
{
Thread.Sleep(100);
Dispatcher.FromThread(MainThread).BeginInvoke(new Action(() =>
{
int PercentageValue = (int)(0.5f + ((100f * i) / Entities.Count));
StaticDataProperties.ProgBar.Value = PercentageValue;
}));
}
}));
backgroundThread.Start();
return Status;
}
catch (Exception ex)
{
ErrorException = ex.Message;
return false;
}
}
To fix your problem you could use Thread.Join and do this, place this logic before return statement..
backgroundThread.Join(); // blocks calling thread.
There's two general directions you can attempt to take:
Dirty approach:
Add a temprary boole that is true while the "inner" thread is still running and handle the logic that should be handled after this after a "while"-statement on that boole.
(the while-statement would keep the code looping/"paused" untill the boole's value is falsey)
Neat approach:
Using async tasks and a callback function.
Instead of using threads which use too much memory you can use Tasks and async/await like Charles Mager suggested
private async void AccessElements()
{
TaxoProcess Taxo = new TaxoProcess();
if (await Taxo.AccessEntity())
{
MessageBox.Show("Succesfully Extracted Data", "Extract Application", MessageBoxButton.OK, MessageBoxImage.Information);
}
}
public async Task<bool> AccessEntity()
{
return Task.Run(() =>
{
try
{
for (int i = 0; i < Entities.Count; i++)
{
await Task.Delay(100);
int PercentageValue = (int)(0.5f + ((100f * i) / Entities.Count));
StaticDataProperties.ProgBar.Value = PercentageValue;
}
return true;
}
catch (Exception ex)
{
ErrorException = ex.Message;
return false;
}
});
}
This is shorter and does all the thread managements in the background
I have the code below which works fine when the Session state is InProc. However when the Session state is Sql Server, HandleCallback never gets called. How do I change the code so HandleCallBack gets called?
private void TAdata(object sender, EventArgs e)
{
if (((Form)sender).DialogResult == DialogResult.No)
{
return;
}
if (Changed)
{
MessageBox.Show(this.ParentForm, "Save Payroll Changes First", "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
else
{
SqlConnection dbconnAS = new SqlConnection(strDBconnAS);
{
try
{
AsyncCallback callback = new AsyncCallback(HandleCallback);
using (SqlCommand SQLcmd = new SqlCommand("dbo.KronosTaData", dbconnAS))
{
SQLcmd.CommandType = CommandType.StoredProcedure;
dbconnAS.Open();
Changed = true;
SQLcmd.BeginExecuteNonQuery(callback, SQLcmd);
strResult = "";
ExportProgress.Visible = true;
ExportProgress.Value = 0;
ExportProgress.Maximum = 120;
ExportTimer.Start();
}
}
catch (Exception ex)
{
Changed = false;
strResult = ex.Message;
if (dbconnAS != null)
{
dbconnAS.Close();
}
}
}
}
}
private void HandleCallback(IAsyncResult result)
{
try
{
using (SqlCommand SQLcmd = (SqlCommand)result.AsyncState)
{
int rowCount = SQLcmd.EndExecuteNonQuery(result);
strResult = "OK";
SQLcmd.Connection.Close();
}
}
catch (Exception ex)
{
strResult = ex.Message;
}
}
private void ExportTimer_Tick(object sender, EventArgs e)
{
//Timer Exists on UI thread
if (strResult == "")
{
if (cmdKronos.Enabled) cmdKronos.Enabled = false;
if (ExportProgress.Value > ExportProgress.Maximum - 10) ExportProgress.Maximum += 10;
ExportProgress.Value += 1;
}
else if (strResult == "OK")
{
Changed = false;
cmdKronos.Enabled = true;
ExportProgress.Visible = false;
ExportTimer.Stop();
MessageBox.Show(ParentForm, "Kronos data succesfully imported", "Data Import", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
else
{
Changed = false;
cmdKronos.Enabled = true;
ExportProgress.Visible = false;
ExportTimer.Stop();
MessageBox.Show(ParentForm, Text, "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
}
You are disposing the command as soon as you've finished starting it:
using (SqlCommand SQLcmd = new SqlCommand("dbo.KronosTaData", dbconnAS))
{
//...
SQLcmd.BeginExecuteNonQuery(callback, SQLcmd);
//...
}
that will abort everything - so indeed: it will never complete. Basically; using doesn't play nicely with Begin*/End*, so don't do that. You might find it much easier to do this using async/await, by the way (via ExecuteNonQueryAsync).
You also probably want to close and dispose the connection somewhere; again, async/await would make this much easier to get right.
The solution is to declare the variable strResult as static.
See Visual Webgui Variable Scope
For now I was using Parallel methods to check urls for 200 status code, but this was slow method. Now I'm trying to move my code to await/async methods but it doesn't working
private async void button1_Click(object sender, EventArgs e)
{
DateTime start = DateTime.Now;
var timerPostingSpeed = new Timer(state =>
{
TimeSpan elapsed = DateTime.Now - start;
string postingSpeed = string.Format("{0:0}",
finishedUrls * 60 / (int)elapsed.TotalSeconds);
UpdatingLabel(label1, postingSpeed);
}, null, 5000, 10000);
IEnumerable<string> urls = File.ReadLines("urls.txt");
var engine = Python.CreateEngine();
var scriptSource =
engine.CreateScriptSourceFromString(#"
if Open(__URL).Result:
print 1
");
await urls.ForEachAsync(20, async line =>
{
try
{
var adderEngine = new SpeedEngine();
// int zz = await adderEngine.Open(line);
// return;
ScriptScope scope = engine.CreateScope();
scope.SetVariable("__URL", line);
scope.SetVariable("Open",
new Func<string, Task<int>>(adderEngine.Open));
try
{
await scriptSource.Execute(scope);
}
catch (UnboundNameException une)
{
MessageBox.Show(une.Message,
msg.
MySeoBoxForm_startPostingToolStripButton_Click_Unbound_Name_Error,
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
catch (SyntaxErrorException see)
{
MessageBox.Show(
string.Format("{0}\nLine: {1}\nCode: {2}",
see.Message,
see.Line, see.GetCodeLine()),
msg.
MySeoBoxForm_startPostingToolStripButton_Click_Syntax_Error,
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
catch (MissingMemberException mme)
{
MessageBox.Show(mme.Message, "Missing Member",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
catch (ArgumentTypeException ate)
{
MessageBox.Show(string.Format("{0}", ate.Message),
msg.
MySeoBoxForm_startPostingToolStripButton_Click_Syntax_Error,
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
catch (SystemExitException)
{
}
catch (Exception exc)
{
MessageBox.Show(string.Format("{0}", exc.Message),
msg.
MySeoBoxForm_startPostingToolStripButton_Click_Syntax_Error,
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
finally
{
MessageBox.Show(string.Format("{0}","OK"),
msg.
MySeoBoxForm_startPostingToolStripButton_Click_Syntax_Error,
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
catch (Exception exc)
{
MessageBox.Show(string.Format("{0}", exc.Message),
msg.
MySeoBoxForm_startPostingToolStripButton_Click_Syntax_Error,
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
finally
{
Interlocked.Increment(ref finishedUrls);
numericUpDown1.Invoke(new MethodInvoker(delegate
{
numericUpDown1.Value++;
}));
}
});
timerPostingSpeed.Dispose();
}
}
public async Task<int> Open(string siteUrl)
{
Uri newUri;
if (!Uri.TryCreate(siteUrl, UriKind.Absolute, out newUri)) return 0;
_uri = _openUri = newUri;
_req = new HttpRequestMessage(HttpMethod.Get, _uri);
_response = await _httpClient.SendAsync(_req);
if (_response == null || !_response.IsSuccessStatusCode)
{
return 0;
}
return 1;
}
I need to use Iron Python - without it (when I uncomment await adderEngine.Open(line); return;) everything works ok. But with Iron Python my app stopped at *_response = await _httpClient.SendAsync(_req);* without errors. Also I noticed when I replace
await urls.ForEachAsync(20, async line =>
with:
await urls.ForEachAsync(1, async line =>
it's working
ForEachAsync: http://blogs.msdn.com/b/pfxteam/archive/2012/03/05/10278165.aspx
Any help?
If your Python code is calling Task.Result, and you're on a UI thread (as appears to be the case), you can cause a deadlock (I explain this fully on my blog). In short, the async method (Open) is trying to resume execution on the UI thread, but the UI thread is blocked by calling Result.
AFAIK, Python does not have async/await support, but you should be able to use ContinueWith (meh) or write some kind of bridge between Task and Twisted's Deferred (much cooler).
I have several services and use threads to implement each one. The services are executed sequentially. Let me just pick up one for demo purpose.
services[1] = new RProcessing() { ConsoleInfoColor = ConsoleColor.Cyan };
success = services[1].Start();
if (success)
{
OutputUtils.WriteLogInfo("Service " + services[1].Name + " started...");
}
else
{
OutputUtils.WriteLogInfo("Service " + services[1].Name + " failed to start...");
previousStartup = false;
services[0].Stop();
}
Inside RProcessing.
public RProcessing()
{
worker = new Thread[1]; // Only one thread
for (int i = 0; i < 1; i++)
{
worker[i] = new Thread(new ThreadStart(ServiceLoop));
worker[i].Name = "R Thread_" + i.ToString();
}
// processing
}
public bool Start()
{
foreach (Thread t in worker)
t.Start();
return (true);
}
public bool Stop()
{
if (_isRunning)
{
_isRunning = false;
}
_isRunning = false;
base.Dispose();
WriteLogInfo("Shutdown of R Processor complete");
return (true);
}
public void ServiceLoop()
{
_isRunning = true;
WriteLogInfo("Starting ServiceLoop() for: " + Assembly.GetAssembly(typeof(RProcessing)).FullName);
string s;
while (_isRunning)
{
Thread.Sleep(500);
s = null;
try
{
WriteLogInfo(" processing "+s);
Thread.Sleep(864);// 24 hours.
}
catch (Exception ex)
{
WriteLogError("Thread " + Thread.CurrentThread.Name + " " + ex.ToString());
}
}
if (this._isRunning)
{
WriteLogInfo("Restarting thread due to failure...");
try
{
Thread.CurrentThread.Start();
}
catch (Exception ex)
{
WriteLogError("Error restarting thread... " + ex.ToString());
}
}
}
Only there is one thread, I want to finish it then go back the next service. However it is always inside the ServiceLoop. How can break it? Just call Stop()?
Well, comment is misleading. Thread will sleep for 864 milliseconds, and not 24 hours.
Thread.Sleep(864);// 24 hours.
If you really intend to sleep that long in a loop, then use ManualResetEvent so that you could abort the wait at any time.
ManualResetEvent cancelEvent;
in loop:
if(cancelEvent.WaitOne(TimeSpan.FromHours(24))){
break;
}
and, in Stop method:
cancelEvent.Set();
Also remove that:
if (this._isRunning)
{
WriteLogInfo("Restarting thread due to failure...");
try
{
Thread.CurrentThread.Start();
}
catch (Exception ex)
{
WriteLogError("Error restarting thread... " + ex.ToString());
}
}
And make sure that _isRunning is volatile, otherwise it may be cached and not updated in another thread. Your service will exit peacefully when you call Stop().