multithreading

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.




Answer this question

multithreading

  • THE RAZI

    Russ, it is a lot of code. Specifically, what part do you want

  • vakman

    (sender as BackgroundWorker).ReportProgress(currentLoop);

    So far no luck--the same thing: not updating.



  • pd_tch

    Well, it is an unexpected solution! Thank you. Maybe it is the way to go. I've already put some code in and it compiled.

  • nino_emcee

    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();

    }

    }

    }



  • Lehmberg

    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


  • RMon

    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


  • Mark Willer

    Alex,

    Could you post your code

    Thanks,
    Russ


  • Shady9399

    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;
    }



  • redshock

    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;

    }

    }



  • Corres

    "I set WorkerProgressBar = true;"

    That should have been: worker.WorkerReportsProgress = true;

    Sorry.



  • mark brayton

    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);
    }


  • cwlaualex

    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



  • aragon

    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


  • _hunter

    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.



  • multithreading