I need to do multithreading. It is my fist attempt. It failed. This is the setup:
There is a form with tabControl and a few pages. There is a progress bar on one of them. It is supposed to measure progress of file downloading. WIthout multhithreading it is dead while the files are downloaded and then in the end it jumps to 100%.
This is what I did. Everything compiled but the progress never was activated even after the downloading was over. In other words my code actually made the things worse.
In the main form I put in this code at the start of procedure that is handling the download:
ThreadStart threadDelegate = new ThreadStart ( Work.DoWork );
Thread newThread = new Thread ( threadDelegate );
newThread.Start ( );
Then in the loop that does downloading I put this in:
Thread.Sleep ( 0 );
Work work = new Work ( );
work.data = prg; // prg is a calculated % of the work done.
After the loop ends there is a statement:
newThread.Abort();
In a separate *cs file I created a class like this:
class Work
{
public int data;
public static void DoWork ( )
{
Form1 ff1 = new Form1 ( ); // Form1 is my main form
Work works = new Work ( );
ff1.progressBar_Gr1pg3.Value = works.data; // this is the progress bar on page3
}
}
I hope I did not miss anything essential. As I said I never saw any fruit of this code.
It is a test code for me. In fact I can live without this progress bar. I need multithreading for other things.
Please help.

multithreading
Suresh NR
Basically the section where you are updating the backgroundWorker component.
It should be working, so I'd like to see what's going on.
Thanks,
Russ
LastCyborg
"I set WorkerProgressBar = true;"
That should have been: worker.WorkerReportsProgress = true;
Sorry.
nikos_22
Heres a threaded version:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Net;
namespace WindowsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
DownloadFile("http://download.freewarefiles.com/files/foobar2000_0.9.4.exe", "C:\\test.exe");
}
bool pMaxSet;
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
if (!pMaxSet)
{
pMaxSet = true;
progressBar1.Maximum = e.ProgressPercentage;
return;
}
progressBar1.Value = e.ProgressPercentage;
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
MessageBox.Show("Download Complete");
}
private void DownloadFile(string sURL, string Filename)
{
System.Net.HttpWebRequest URLReq;
System.Net.HttpWebResponse URLRes;
System.IO.FileStream FileStreamer;
byte[] bBuffer = new byte[1024];
int pMax = 0;
int pValue = 0;
int iBytesRead = 0;
FileStreamer = new FileStream(Filename, System.IO.FileMode.Create);
URLReq = (HttpWebRequest)System.Net.WebRequest.Create(sURL);
URLRes = (HttpWebResponse)URLReq.GetResponse();
using (Stream sChunks = URLReq.GetResponse().GetResponseStream())
{
pMax = Convert.ToInt32(URLRes.ContentLength);
backgroundWorker1.ReportProgress(pMax);
do
{
iBytesRead = sChunks.Read(bBuffer, 0, 1024);
FileStreamer.Write(bBuffer, 0, iBytesRead);
if (pValue + iBytesRead <= pMax)
{
pValue += iBytesRead;
backgroundWorker1.ReportProgress(pValue);
}
else
backgroundWorker1.ReportProgress(pMax);
}
while (iBytesRead != 0);
backgroundWorker1.ReportProgress(pMax);
sChunks.Close();
FileStreamer.Close();
}
}
private void Form1_Click(object sender, EventArgs e)
{
backgroundWorker1.RunWorkerAsync();
}
}
}
MJC2006
I just had a similar situation, and I got rid of the timer altogether. Instead I used the backgroundWorker component:
http://msdn2.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx
Good luck,
Russ
MarioMario
Thank you. This is the routine you may be looking for. I did some minor surgery on it for clarity. Hopefully I did not remove anything essential:)
public TimeSpan subPushHTTPrequestAll_Click ( BackgroundWorker worker, Object sender, DoWorkEventArgs e )
{
string symbol;
int numberToDownload = this.comboSymbols.Items.Count - 1;
Class2 class2 = new Class2 ( );
ThreadStart threadDelegate = new ThreadStart ( Work.DoWork );
Thread newThread = new Thread ( threadDelegate );
newThread.Start ( );
DateTime dateTimeStart = System.DateTime.Now;
// one way to get all .csv files is:
// process the list of files found in the directory.
string thePath = Application.StartupPath;
string cur_drive = thePath.Substring ( 0, 2 );
string targetDirectory = cur_drive + @"\VFP_Projects\Data\Stoxx\";
string[] fileEntries = Directory.GetFiles ( targetDirectory );
char[] delim = {'\\'};
string[] namesArr = new string[1];
// second way is to get them from ComboSymbols.DataSource
for ( int ii = 0; ii <= this.comboSymbols.Items.Count - 1; ii++ )
{
symbol = ( string )this.comboSymbols.Items[ii];
symbol = symbol.Trim ( );
int switched = ( ii + 1 ) % 10;
float proggr = ii / numberToDownload * 100f;
int prg = (int) proggr;
(sender as BackgroundWorker).ReportProgress ( prg );
Boolean returns = class2.getOneCSVfromYahoo ( symbol );
if ( returns != true )
{
Console.WriteLine ( "COULD NOT REFRESH: ", symbol );
Console.WriteLine ( symbol );
}
else
{
// will see if the company name is missing in correlates.dbf
if ( Globals.flaggedEmpty == true )
{
string sql1 = "SELECT * FROM 'correlates.dbf'";
string inpStr1 = "stoxx";
DataTable dt1 = Class2.getData ( sql1, class2.getConnStrings ( ref inpStr1 ) );
foreach ( DataRow row in dt1.Rows )
{
if ( (( string )row["named"]).Trim ( ) == "" )
{
Console.WriteLine ("empty: {0} ", ( string )row["named"] );
row["named"] = Globals.named;
Console.WriteLine ( "changed : {0} ", ( string )row["named"] );
}
}
dt1.AcceptChanges ( );
}
}
} // end of loop for all companies. The company name ends up in Globals.named
DateTime dateTimeEnd = DateTime.Now;
TimeSpan span = dateTimeEnd - dateTimeStart;
Console.WriteLine ( "the time spent : {0}", span );
return span;
}
schyffe
Acts7
private bool DownloadFile(string sURL, ProgressBar pProgress, string Filename)
{
System.Net.HttpWebRequest URLReq;
System.Net.HttpWebResponse URLRes;
System.IO.FileStream FileStreamer;
byte[] bBuffer = new byte[1024];
int iBytesRead = 0;
try
{
FileStreamer = new FileStream(Filename, System.IO.FileMode.Create);
URLReq = (HttpWebRequest)System.Net.WebRequest.Create(sURL);
URLRes = (HttpWebResponse)URLReq.GetResponse();
using (Stream sChunks = URLReq.GetResponse().GetResponseStream())
{
pProgress.Maximum = Convert.ToInt32(URLRes.ContentLength);
do
{
iBytesRead = sChunks.Read(bBuffer, 0, 1024);
FileStreamer.Write(bBuffer, 0, iBytesRead);
if (pProgress.Value + iBytesRead <= pProgress.Maximum)
{
pProgress.Value += iBytesRead;
}
else
pProgress.Value = pProgress.Maximum;
}
while (iBytesRead != 0);
pProgress.Value = pProgress.Maximum;
sChunks.Close();
FileStreamer.Close();
return true;
}
}
catch (Exception ee)
{
MessageBox.Show(ee.Message);
return false;
}
}
ajcanable
(sender as BackgroundWorker).ReportProgress(currentLoop);
So far no luck--the same thing: not updating.
Mastan Oli
Alex,
Could you post your code
Thanks,
Russ
Futzy
It sounds like you aren't updating the progressBar while the second thread is executing.
I'm not sure what your processing is, but for example if you were using a loop:
i = 1;
for (i = 1; i <= 1000; i++){
//do your work here
currentLoop = i;(sender as BackgroundWorker).ReportProgress(currentLoop);
}
Tej62007
Russ hi,
If you have a chance to read this: I got the BacgroundWorker working. It definitely runs and performs as needed with one minor but nasty surprise. It does not handle the progress bar. I mean it showed me the final result only, pretty much as I had before. The progress bar was blank during the procedure (file downloading) and after downloading was finished it went all the way up.
I set WorkerProgressBar = true; I do not know what else I can do for it to work.
Any suggestions
Also it refused to interact with any user-interface controls along the way. This is of course a part of the class description. There is a warning about it. So I have to do some additional coding but since the progress bar does not work, it is unclear if the other controls (label, textBox) will be reactive either.
Did you get your progress bar working
In any event I needed multithreading for other things more than for this. From this standpoint I am quite grateful to you for the suggestion.
Thanks.
elkadeem
I'm by no means an expert, but I feel like I am missing something here. Why not just use:
(sender as BackgroundWorker).ReportProgress(ii);
It seems like you are doing extra math and casting that isn't necessary.
Let me know if that make any difference.
Thanks,
Russ
kokob007
RobertSHarper
Hi cab,
This is cute but does not seem to be a separate thread. Could you comment on the advantage of this code from your point of view
It seems to me pretty much what I have got or close.
I wish I could give you a job:)
Thanks