HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(baseurl + url);
req.Timeout = 1000 * 10;
HttpWebResponse response = (HttpWebResponse)req.GetResponse();
Stream str = response.GetResponseStream();
HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
doc.Load(str);
response.Close();
string imgurl = doc.DocumentNode.SelectSingleNode("//div[#class='one-page']/a/img[#class='manga-page']").Attributes["src"].Value;
req = (HttpWebRequest)HttpWebRequest.Create(imgurl);
req.Timeout = 1000 * 10;
response = (HttpWebResponse)req.GetResponse();
str = response.GetResponseStream();
Image img = Image.FromStream(str);
response.Close();
return img;
I run this code in a loop (using several threads) to download about 4000 images, and it works brilliantly for the first hundreds but then (at a different point in time for every time I try) it suddenly stops working, and every call to "req.GetResponse()" results in an TimeoutException. I have no idea of why this happen and no idea of what might be wrong or how to deal with it. Any help would be highly appreciated.
The code I use to run this function (it's called GetPage(int) and called as c.GetPage(t)) is as following:
for (int j = 0; j < 2; j++)
{
BackgroundWorker bw = new BackgroundWorker();
num[bw] = j;
bgs.Add(bw);
bw.DoWork += (object sender, DoWorkEventArgs doargs) =>
{
int t = -1;
lock (lockObjForQueueOperations)
{
if (images.Count != 0)
t = images.Dequeue();
}
if(t < 0)
{
doargs.Result = false;
return;
}
currently[sender] = t;
Image img;
try { img = c.GetPage(t); }
catch (Exception e)
{
lock (lockObjForQueueOperations)
{
images.Enqueue(t);
}
lock (Console.Title)
{
if (num[sender] == 0) Console.ForegroundColor = ConsoleColor.Cyan;
else if (num[sender] == 1) Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine("**ERR: Error fetshing page {0}, errormsg: {1}", t, e.Message);
Console.ForegroundColor = ConsoleColor.White;
}
doargs.Result = true;
Thread.Sleep(1000*2);
return;
}
lock (Console.Title)
{
if (num[sender] == 0) Console.ForegroundColor = ConsoleColor.Cyan;
else if (num[sender] == 1) Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine("\t\tLoaded page {0} of {1}.", t + 1, c.PagesCount);
Console.ForegroundColor = ConsoleColor.White;
}
string imgpath = Path.Combine(ndir, "Page " + (t + 1) + ".png");
img.Save(imgpath, System.Drawing.Imaging.ImageFormat.Png);
img.Dispose();
doargs.Result = true;
};
bw.RunWorkerCompleted += (object sender, RunWorkerCompletedEventArgs runargs) =>
{
if ((bool)runargs.Result) bw.RunWorkerAsync();
else
{
finnishedworkers++;
if (finnishedworkers == 2) restetter.Set();
bw.Dispose();
}
};
bw.RunWorkerAsync();
}
The Timeout property in the HttpWebRequest is in milliseconds. Currently setting it to 10,000 is only 10 seconds, and that might not be enough based off of bandwidth and the size of the data being pulled as well as the complexity of the code being run. I say try increasing that first.
You have a bad design. Instead of creating threads for every request, try calling BeginGetResponse. The framework will handle allocating threads from the threadpool to service your requests.
Add a call to ServicePointManager.SetDefaultConnectionLimit (?) not sure of this to a number like 100.
create a semaphore with a count matching the connection limit count.
In your function that calls BeginGetResponse add a call to semaphore.WaitOne() just before your call get BeginGet...
In your EndGetResponse() handler, call semaphore.Release() to allow the next request to continue.
You are probably exhausting the threadpool with all of your own threads. Monitor your process and see if you can't execute and only use 5-10 threads total, ever. Maybe you could log Thread.Current.ThreadID to see how the SAME thread handles multiple requests.
Done this billions of time. Really.
Related
Hello i created a program which reads serial data from a scoreboard, then depending on the string the program separates the data into different boxes on the form and then to different txt files.The purpose of this, is to use those txt files for livestreaming purposes in basketball games.
It's the first time i work with serial data and i am not a very experienced programmer.
My problem, as the title of this post suggests is that every now and then without any reason i am loosing some packages. This is happening randomly , for example in 10 second period i could 1 package while the next one none or 4.
private void ReadData()
{
Thread MyThread = null;
{
try
{
ThreadStart ThreadMethod = new ThreadStart(ReadFromPort);
MyThread = new Thread(ThreadMethod);
}
catch (Exception e)
{
Console.WriteLine("Failed to create thread! " + e.Message);
return;
}
try
{
MyThread.Start();
}
catch (Exception e)
{
Console.WriteLine("The thread failed to start! " + e.Message);
}
}
}
//Recieves data and write them on textbox (optionally on a txt)
private void ReadFromPort()
{
while (Receiver == true)
{
try
{
int count = ComPort.BytesToRead;
System.Windows.Forms.Application.DoEvents();
byte[] data = new byte[count];
ComPort.Read(data, 0, data.Length);
currentMessage = Combine(currentMessage, data);
ReceivedData = (BitConverter.ToString(data));
if (count > 0)
{
if (chBoxUpdate.Checked)
{
DataType = count;
tempData = ReceivedData;
this.Invoke(new EventHandler(DisplayText));
if (chboxTxt.Checked)
{
this.Invoke(new EventHandler(ExportData));
}
}
else if (chBoxPrevious.Checked)
{
DataType = count;
tempData = ReceivedData;
this.Invoke(new EventHandler(ClearData));
this.Invoke(new EventHandler(DisplayText));
if (chboxTxt.Checked)
{
this.Invoke(new EventHandler(ExportData));
}
}
}
}
catch (Exception e)
{
}
}
}
//Displays Text
private void DisplayText(object sender, EventArgs e)
{
string temp;
Console.WriteLine(tempData+ " (" + tempData.Length.ToString() + ")");
try
{
if (tempData.Length == 38)// && ReceivedData.Substring(12, 5) == "03-02")
{
if (tempData.Substring(12, 5) == "03-02")
{
DataText.AppendText(tempData.Substring(24, 8));
DataText.AppendText("\n");
Blink.Text = "Reading...";
timer1.Start();
timer1.Enabled = true;
}
}
else
if (tempData.Length == 35)
{
if (tempData.Substring(12, 5) == "45-02")
{
AttackTime.AppendText(tempData.Substring(24, 5));
Blink.Text = "Reading...";
AttackTime.AppendText("\n");
timer1.Start();
timer1.Enabled = true;
}
}
else
if (tempData.Length == 29)
{
if (tempData.Substring(12, 5) == "03-36")
{
HomeScore.AppendText(tempData.Substring(21, 2));
Blink.Text = "Reading...";
HomeScore.AppendText("\n");
timer1.Start();
timer1.Enabled = true;
}
else
if (tempData.Substring(12, 5) == "03-46")
{
AwayScore.AppendText(tempData.Substring(21, 2));
Blink.Text = "Reading...";
AwayScore.AppendText("\n");
timer1.Start();
timer1.Enabled = true;
}
}
}
catch (ArgumentOutOfRangeException)
{
}
}
Keep in mind that tempData and ReceivedData are the same here and as the programs appears now there's not any particular reason to set tempData=ReceivedData.This is a part of a different,older code i used in the begining which i never changed but it doesn't effect the program.
At first i am using a thread to enable the ReadFromPort then if the program finds that there are available data in line it displays them with the DisplayText and it's using the ExportData to export the data to a txt.I think the problem is somewhere there but as i am not very experienced i can't tell where.
Are there any suggestions on how to improve my code? If you more details or information i can provide them.
You are using Invoke, this blocks the caller thread until the event has been processed, and since you are updating the UI this can take some time. This probably causes some buffer to overflow and data to be discarded. So you should do as little work as possible on the reading thread.
There are a few alternatives
Put the data on a concurrentQueue, and let the UI thread have a timer that periodically triggers a method that reads from the queue and updates the UI.
Put the data on a concurrentQueue, wrapped in a blocking collection, have another background thread iterate over the blocking collection, using GetConsumingEnumerable, and post the result to the main thread once done. This would be suitable if there is significant processing to be done.
Use BeginInvoke to post the received data to the main-thread, this does not wait for the call to complete, but probably have slightly higher overhead that the previous alternatives. I would recommend not accessing any UI properties from the background thread, since by default no property of a UI class is threadsafe. Even if you might get away with it if you are only reading, I would not take the chance.
This is the method that calculate the speed of download:
private void CalculateDownload(int ln, BackgroundWorker backw)
{
string speed;
DateTime DownloadStart = DateTime.Now;
int dnsize = ln;
if (dnsize > 0)
{
DateTime DownloadEnd = DateTime.Now;
TimeSpan DownloadSub = DownloadEnd.Subtract(
DownloadStart);
speed = string.Format("Download speed: {0:F0} bps\n",
(dnsize / DownloadSub.TotalMilliseconds) * 1000);
backw.ReportProgress(0,speed);
}
}
And this is the method i'm using to download a file from ftp server. Each time a single file.
public int FtpDownload(object sender, string file, string filesdirectories, string fn)
{
string tmp = "";
BackgroundWorker bw = sender as BackgroundWorker;
string filenameonly = Path.GetFileName(file);
string ftpdirectories = Path.Combine(ftpcontentdir, filesdirectories);
string fileurl = "ftp://" + file;
FtpWebRequest reqFTP;
reqFTP = (FtpWebRequest)FtpWebRequest.Create(fileurl);
reqFTP.Credentials = new NetworkCredential(UserName, Password);
reqFTP.UseBinary = true;
reqFTP.UsePassive = true;
reqFTP.KeepAlive = true;
reqFTP.Method = WebRequestMethods.Ftp.DownloadFile;
try
{
FtpWebResponse response = (FtpWebResponse)reqFTP.
GetResponse();
Stream responseStream = response.GetResponseStream();
StreamReader reader = new StreamReader(responseStream);
tmp = reader.ReadToEnd();
CalculateDownload(tmp.Length, bw);
reader.Close();
response.Close();
}
catch (WebException e)
{
Console.WriteLine(e.ToString());
}
return tmp.Length;
}
The first file download in the CalculateDownload method i'm getting the file size:
The variable ln is for example 66349
Then the variable speed contain: Download speed: 21367 bps
In the next file:
ln = 59892
Then speed is: Download speed: 25100 bps
That is working fine when i'm using breakpoint but if i'm not using a breakpoint instead 25100 bps i will see infinity bps
In form1 i'm sending the file to download like this:
private void backgroundWorker2_DoWork(object sender, DoWorkEventArgs e)
{
for (int i = 0; i < numberOfFiles.Count; i++)
{
int fn = numberOfFiles[i].IndexOf(txtHost.Text, 0);
string fn1 = numberOfFiles[i].Substring(txtHost.Text.Length + 1, numberOfFiles[i].Length - (txtHost.Text.Length + 1));
string dirs = Path.GetDirectoryName(fn1);
string filename = Path.GetFileName(fn1);
ftpProgress1.FtpDownload(sender, numberOfFiles[i], dirs, filename);
}
}
And the progress changed event in form1:
private void backgroundWorker2_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
this.toolStripStatusLabel1.Text = e.UserState.ToString();
}
Why when i'm using breakpoint it's showing every file the speeed the time was downloaded but without breakpoint it's showing infinity ?
Division by 0 gives out infinity when using floats or doubles.
You could add an additional check to see if 0 miliseconds is elapsed
and in that case not calculate the value. At Time = 0, since nothing is downloaded
yet the value is probably not useful to the user.
You could also add unit tests by passing a class that implements an interface with the right
methods to simulate the call to back.ReportProgress such as:
private void CalculateDownload(int ln, IBackgroundWorker backw)
to figure out what happens at Time = 0, Time = 1 and so on.
Finally that line:
int dnsize = ln;
is not useful since you already have the variable passed to your function
If you get a result when using a break point, but infinity when you let it run, I suspect you are downloading it in less than 1ms, so you are dividing by 0. You could try a larger file to see if you get a better result without break points. Alternatively consider something mote accurate like DateTime.Ticks.
Note, string.length will be bytes not bits.
So I am trying to create a basic WinForm Application that uses SNMP, from snmpsharpnet.
I have two buttons 'Eye' and 'Jitter' that when one is pressed a timer starts which executes SNMP code inside the timer handler every minute.
I am trying to write the SNMP output to a textbox from the timer handler but everything I try either leads to thread exceptions or a continuous running process when I exit the program.
I have tried so many different things to fix those two errors that I may be screwing everything up but here is the code I have:
using System;
using System.Net;
using SnmpSharpNet;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public static bool stop = false;
static bool min = false, sec = false, eye = false, jitter = false;
static string ipAdd = "";
static System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();
static int alarmCounter = 1;
static bool exitFlag = false;
static TextBox textbox;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
textbox = outputBox;
}
private void IPtext_TextChanged(object sender, EventArgs e)
{
ipAdd = IPtext.Text;
}
private void stopButton_Click(object sender, EventArgs e)
{
stop = true;
timer.Stop();
}
// This is the method to run when the timer is raised.
private static void TimerEventProcessor(Object myObject,
EventArgs myEventArgs)
{
timer.Stop();
// If stop button has not been pressed then continue timer.
if (stop == false)
{
textbox.Clear();
// Restarts the timer and increments the counter.
alarmCounter += 1;
timer.Enabled = true;
/*
textbox.Invoke(
new MethodInvoker(
delegate { textbox.AppendText("fsjdaò"); }));
*/
System.IO.StreamWriter file;
if (eye == true)
{
file = new System.IO.StreamWriter("c:/Users/bshellnut/Desktop/Eye.txt", true);
}
else
{
file = new System.IO.StreamWriter("c:/Users/bshellnut/Desktop/Jitter.txt", true);
}
// SNMP community name
OctetString community = new OctetString("public");
// Define agent parameters class
AgentParameters param = new AgentParameters(community);
// Set SNMP version to 2 (GET-BULK only works with SNMP ver 2 and 3)
param.Version = SnmpVersion.Ver2;
// Construct the agent address object
// IpAddress class is easy to use here because
// it will try to resolve constructor parameter if it doesn't
// parse to an IP address
IpAddress agent = new IpAddress(ipAdd);
// Construct target
UdpTarget target = new UdpTarget((IPAddress)agent, 161, 2000, 1);
// Define Oid that is the root of the MIB
// tree you wish to retrieve
Oid rootOid;
if (eye == true)
{
rootOid = new Oid("1.3.6.1.4.1.128.5.2.10.14"); // ifDescr
}
else
{
rootOid = new Oid("1.3.6.1.4.1.128.5.2.10.15");
}
// This Oid represents last Oid returned by
// the SNMP agent
Oid lastOid = (Oid)rootOid.Clone();
// Pdu class used for all requests
Pdu pdu = new Pdu(PduType.GetBulk);
// In this example, set NonRepeaters value to 0
pdu.NonRepeaters = 0;
// MaxRepetitions tells the agent how many Oid/Value pairs to return
// in the response.
pdu.MaxRepetitions = 5;
// Loop through results
while (lastOid != null)
{
// When Pdu class is first constructed, RequestId is set to 0
// and during encoding id will be set to the random value
// for subsequent requests, id will be set to a value that
// needs to be incremented to have unique request ids for each
// packet
if (pdu.RequestId != 0)
{
pdu.RequestId += 1;
}
// Clear Oids from the Pdu class.
pdu.VbList.Clear();
// Initialize request PDU with the last retrieved Oid
pdu.VbList.Add(lastOid);
// Make SNMP request
SnmpV2Packet result;
try
{
result = (SnmpV2Packet)target.Request(pdu, param);
//textbox.Text = "";
}
catch (SnmpSharpNet.SnmpException)
{
textbox.Invoke(
new MethodInvoker(
delegate { textbox.AppendText("Could not connect to the IP Provided."); }));
timer.Stop();
//outputBox.Text += "Could not connect to the IP Provided.";
break;
}
// You should catch exceptions in the Request if using in real application.
// If result is null then agent didn't reply or we couldn't parse the reply.
if (result != null)
{
// ErrorStatus other then 0 is an error returned by
// the Agent - see SnmpConstants for error definitions
if (result.Pdu.ErrorStatus != 0)
{
// agent reported an error with the request
/*Console.WriteLine("Error in SNMP reply. Error {0} index {1}",
result.Pdu.ErrorStatus,
result.Pdu.ErrorIndex);*/
textbox.Invoke(
new MethodInvoker(
delegate { textbox.AppendText("Error in SNMP reply. " + "Error " + result.Pdu.ErrorStatus + " index " + result.Pdu.ErrorIndex); }));
//outputBox.Text = "Error in SNMP reply. " + "Error " + result.Pdu.ErrorStatus + " index " + result.Pdu.ErrorIndex;
lastOid = null;
break;
}
else
{
// Walk through returned variable bindings
foreach (Vb v in result.Pdu.VbList)
{
// Check that retrieved Oid is "child" of the root OID
if (rootOid.IsRootOf(v.Oid))
{
/*Console.WriteLine("{0} ({1}): {2}",
v.Oid.ToString(),
SnmpConstants.GetTypeName(v.Value.Type),
v.Value.ToString());*/
textbox.Invoke(
new MethodInvoker(
delegate { textbox.AppendText(v.Oid.ToString() + " " + SnmpConstants.GetTypeName(v.Value.Type) +
" " + v.Value.ToString() + Environment.NewLine); }));
//outputBox.Text += v.Oid.ToString() + " " + SnmpConstants.GetTypeName(v.Value.Type) +
//" " + v.Value.ToString() + Environment.NewLine;
file.WriteLine(v.Oid.ToString() + " " + SnmpConstants.GetTypeName(v.Value.Type) +
" " + v.Value.ToString(), true);
if (v.Value.Type == SnmpConstants.SMI_ENDOFMIBVIEW)
lastOid = null;
else
lastOid = v.Oid;
}
else
{
// we have reached the end of the requested
// MIB tree. Set lastOid to null and exit loop
lastOid = null;
}
}
}
}
else
{
//Console.WriteLine("No response received from SNMP agent.");
textbox.Invoke(
new MethodInvoker(
delegate { textbox.AppendText("No response received from SNMP agent."); }));
//outputBox.Text = "No response received from SNMP agent.";
}
}
target.Close();
file.Close();
}
else
{
// Stops the timer.
exitFlag = true;
}
}
private void eyeButton_Click(object sender, EventArgs e)
{
outputBox.Text = "Connecting...";
eye = true;
jitter = false;
stop = false;
timer.Tick += new EventHandler(TimerEventProcessor);
// Sets the timer interval to 5 seconds.
timer.Interval = 5000;
timer.Start();
// Runs the timer, and raises the event.
while (exitFlag == false)
{
// Processes all the events in the queue.
Application.DoEvents();
}
}
private void jitterButton_Click(object sender, EventArgs e)
{
outputBox.Text = "Connecting...";
eye = false;
jitter = true;
stop = false;
timer.Tick += new EventHandler(TimerEventProcessor);
// Sets the timer interval to 5 seconds.
timer.Interval = 5000;
timer.Start();
// Runs the timer, and raises the event.
while (exitFlag == false)
{
// Processes all the events in the queue.
Application.DoEvents();
}
}
private void Seconds_CheckedChanged(object sender, EventArgs e)
{
min = false;
sec = true;
}
private void Minutes_CheckedChanged(object sender, EventArgs e)
{
min = true;
sec = false;
}
}
}
I believe you are running into a deadlock on the UI thread.
TimerEventProcessor() is called by your instance of System.Windows.Forms.Timer, which runs on the UI thread. When the timer goes off, I believe it puts a message into the UI thread's message queue to call your TimerEventProcessor() method. That method in turn calls textbox.Invoke(), which puts another message into the queue and then waits for it to be processed.
Your UI thread is now stuck, as it is in the middle of processing a message, but must wait until another message is processed before it can continue. The calls to Application.DoEvents() do you no good, as they are not being called once your program enters TimerEventProcessor(). (They're also unnecessary, since your button click handlers wouldn't be blocking the UI thread anyway.)
Since the timer runs on the UI thread, you can get rid of the textbox.Invoke() calls and just access textbox directly.
Summary:
Replace your calls to textbox.Invoke() with direct access to textbox
Remove your calls to Application.DoEvents()
Note: if you got the Application.DoEvents() logic from the MSDN example for using a timer, they put it there so that the application doesn't quit once the Main function completes.
Update: You can see if this is truly the issue by replacing your calls to textbox.Invoke with the following code. If this code works, then you definitely have a UI message queue deadlocking issue. Also, if this does resolve the issue, I would not recommend keeping this as the solution, but rather, addressing the deadlocking as suggested above.
// Make the request asynchronously
System.IAsyncResult asyncResult = textbox.BeginInvoke(
new MethodInvoker(
delegate { /* insert delegate code here */ }));
// Process the message queue until this request has been completed
while(!asyncResult.IsCompleted) Application.DoEvents();
// Clean up our async request
textbox.EndInvoke(asyncResult);
Since you seem to have your code working, you can ignore the above test code.
Your problem is not related to the timer and all the Invoke statements you use are not necessary. The System.Windows.Forms.Timer class operates in the UI thread. Look here: http://msdn.microsoft.com/en-us/library/system.windows.forms.timer.aspx
I have created 2 programs. Both use timers with interval set to 250 milliseconds.
The problem is that my first program doesn't lock then I run it, and the second locks with out giving me ability to click stop button. By saying locks I mean that program runs do it's job until I stop it from VS.
I don't understand why I can't stop my first program while the basic same way work for other program. Any ideas?
Program that locks:
private void btnScan_Click(object sender, EventArgs e)
{
tmrInterval.Interval = (int)nudInterval.Value;
tmrInterval.Start();
}
private void ScanPort(IPAddress address, int port)
{
using (TcpClient client = new TcpClient())
{
IAsyncResult result = client.BeginConnect(address, port, null, null);
if (result.AsyncWaitHandle.WaitOne((int)nudTimeout.Value, false)) txtDisplay.AppendText("Port: " + port + " is open." + Environment.NewLine);
else txtDisplay.AppendText("Port: " + port + " is closed." + Environment.NewLine);
}
}
private void btnStop_Click(object sender, EventArgs e)
{
tmrInterval.Stop();
}
private void tmrInterval_Tick(object sender, EventArgs e)
{
ScanPort(IPAddress.Parse(txtIP.Text), currentPort);
currentPort++;
if (currentPort == nudTo.Value) tmrInterval.Stop();
}
Program that doesn't lock:
void tmrPingInterval_Tick(object sender, EventArgs e)
{
if (txtTo.Text == string.Empty) Ping(IPAddress.Parse(ip2str(startIP)));
else
{
if (currentIP >= endIP) tmrPingInterval.Stop();
Ping(IPAddress.Parse(ip2str(currentIP)));
currentIP++;
}
}
private void btnPing_Click(object sender, EventArgs e)
{
if (txtFrom.Text != string.Empty)
{
txtFrom.Enabled = false;
txtTo.Enabled = false;
txtDisplay.Text = string.Empty;
tsslPingCount.Text = string.Empty;
count = 0;
open = 0;
closed = 0;
tmrPingInterval.Interval = int.Parse(nudInterval.Value.ToString());
try
{
startIP = str2ip(txtFrom.Text);
if (txtTo.Text != string.Empty) endIP = str2ip(txtTo.Text);
currentIP = startIP;
tmrPingInterval.Start();
}
catch
{
MessageBox.Show("Input must be in IP format: 100.100.100.100", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
txtFrom.Enabled = true;
txtTo.Enabled = true;
}
}
else MessageBox.Show("IP field cannot be empty!", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
private void btnStop_Click(object sender, EventArgs e)
{
txtFrom.Enabled = true;
txtTo.Enabled = true;
tmrPingInterval.Stop();
}
private void Ping(IPAddress address)
{
Ping pingSender = new Ping();
PingOptions options = new PingOptions();
if (cbDontFragment.Checked) options.DontFragment = true;
else options.DontFragment = false;
string data = string.Empty;
int dataCounter = 0;
options.Ttl = (int)nudTTL.Value;
for (int i = 0; i < nudData.Value; i++)
{
dataCounter++;
if (dataCounter == 10) dataCounter = 0;
data += dataCounter.ToString();
}
byte[] buffer = Encoding.ASCII.GetBytes(data);
int timeout = 120;
try
{
PingReply reply = pingSender.Send(address, timeout, buffer, options);
if (reply.Status == IPStatus.Success)
{
}
else
{
}
}
catch (Exception ex)
{
txtDisplay.SelectedText += Environment.NewLine + ex.Message;
}
}
I'm going to make a guess here since we don't have enough information. I am guessing that tmrInterval in a System.Windows.Forms.Timer. If that is the case, the what's happening is that when the timer ticks, it is handed as a windows message (the same way that mouse clicks, keystrokes, and everything else that make your application appear 'not frozen' are handled).
In the first application, you are doing something that takes substantial time- opening a TCP port, then waiting for a (presumably) large number of milliseconds until the TCP connects or doesnt, then almost immediately doing it again the next time that the timer ticks. You are literally never giving the application a chance to respond to mouse clicks and keystrokes because the UI thread is busy trying to connect to some random ports somewhere.
In the second application, you are doing something relatively quick- just sending a ping somewhere. what you will probably see in the second application is that your application will 'stutter'- become unresponsive for just a second or less while it pings whatever other machine you pointed it at. It doesn't get hung because the UI thread isn't being given that much work to do.
To fix both of these, you should look into implementing a BackgroundWorker. Timers (of any sort) are not generally considered a good way to spawn background tasks in .NET.
About the first sample:
I guess from the context that the timer is a Windows.Forms.Timer. In the elapsed event you are executing a WaitOne(), and so effectively block the Messagepump.
As a possible solution, replace the Timer with a Threading.Timer to decouple the I/O from the main Thread.
I wanted to write program that will check proxies... I wanted to use mutlithreading but don`t know really how to apply it to my program:
int ktory = 0;
// Button to start multithreading
private void p_check_Click(object sender, EventArgs e)
{
for (int i = 0; i < 10; i++)
{
Thread th = new Thread(test_proxy);
CheckForIllegalCrossThreadCalls = false;
th.Start();
}
}
//This is my function to test proxies
private void test_proxy()
{
try
{
int ile = p_listbox.Items.Count;
string proxy = null;
//'ktory' - means position in listbox
proxy = p_listbox.Items[ktory].ToString();
ktory += 1;
//Splitting on IP and PORT
int gdzie = proxy.IndexOf(":");
string IP = proxy.Remove(gdzie);
string ipp = proxy.Replace(IP + ":", "");
int PORT = Int32.Parse(ipp);
//end o splitting
//My testing of anonimty ( works good don`t need to check)
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(p_proxyjudge.Text);
WebProxy adr_proxy = new WebProxy(IP, PORT);
adr_proxy.UseDefaultCredentials = true;
request.Proxy = adr_proxy;
request.Timeout = 15000;
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Stream stream = response.GetResponseStream();
// Checking if anonymous ( not important)
StreamReader sr = new StreamReader(stream);
while (sr.EndOfStream != true)
{
string checking = sr.ReadLine();
if (!checking.Contains("REMOTE_ADDR ="))
p_work.Items.Add(proxy);
}
sr.Close();
stream.Close();
}
catch (Exception ex)
{
ktory += 1;
}
}
< To code : ile and ktory are just like i, or j as numerous variable >
But my multithreading stops on 10 first proxies or just checks them 10x times as one...
The main problem is to make 10 bots to check proxies and after finished checking one proxy move onto another at listbox (but still others bots work in background)
PLEASE HELP ME :) I`m sitting 2nd day on it and cannot figure it out
You are not locking around access to ktory, which is being altered by multiple threads. Because of this, there is no guarantee that your 10 threads will check 10 different proxies.
Object _lock = new Object();
int ktory=0;
...
private void test_proxy()
{
try
{
int ile = p_listbox.Items.Count;
string proxy = null;
//'ktory' - means position in listbox
lock (_lock) {
proxy = p_listbox.Items[ktory].ToString();
ktory += 1;
}
...