views:

68

answers:

2

I have code that does a web-service request. While doing this request I need a progress-bar to be moving independently.

My problem is that I just need to say run a progress update every 1 or 2 seconds and check to see if progress of the request has been completed.

NetBasisServicesSoapClient client = new NetBasisServicesSoapClient();
            TransactionDetails[] transactions = new TransactionDetails[dataGridView1.Rows.Count - 1];
            for (int i = 0; i < dataGridView1.Rows.Count - 1; i++)
            {
                transactions[i] = new TransactionDetails();
                transactions[i].TransactionDate = (string)dataGridView1.Rows[i].Cells[2].Value;
                transactions[i].TransactionType = (string)dataGridView1.Rows[i].Cells[3].Value;
                transactions[i].Shares = (string)dataGridView1.Rows[i].Cells[4].Value;
                transactions[i].Pershare = (string)dataGridView1.Rows[i].Cells[5].Value;
                transactions[i].TotalAmount = (string)dataGridView1.Rows[i].Cells[6].Value;
            }
            CostbasisResult result = client.Costbasis(dataGridView1.Rows[0].Cells[0].Value.ToString(), dataGridView1.Rows[0].Cells[1].Value.ToString(), transactions, false, "", "", "FIFO", true);
            string result1 = ConvertStringArrayToString(result.Details);
A: 

Create a BackgroundWorker (call the instance "bgw") and type "bgw.DoWork += " followed by TAB TAB. Visual Studio then generates the DoWork event handler method. Copy the code above into the handler and voila.

I don't think it makes sense for you to report progress, since your progress is determined by the duration of the web service request over which you have no influence (and you cannot break it into smaller tasks). As such, just display the "doing work" dialog and initiate the background task to call the web service. When it's done close the "doing work" dialog.

Morten Mertner
+3  A: 

I use Background Workers all the time, they are great for processing long time actions.

from your code

#region Background Work of My Request

    private void ProcessMyRequest()
    {            
        if (!bkgWorkerMyRequest.IsBusy)
        {
            lblMessageToUser.Text = "Processing Request...";
            btnProcessRequest.Enabled = false;
            bkgWorkerMyRequest.RunWorkerAsync();
        }
    }
    private void bkgWorkerMyRequest_DoWork(object sender, DoWorkEventArgs e)
    {
        // let's process what we need in a diferrent thread than the UI thread
        string r = GetStuffDone();
        e.Result = r;
    }
    private void bkgWorkerMyRequest_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        string myResult = (String)e.Result;    

        lblMessageToUser.Text = myResult;
        btnProcessRequest.Enabled = true;
    }

#endregion

    private function string GetStuffDone() 
    {
        NetBasisServicesSoapClient client = new NetBasisServicesSoapClient();
        TransactionDetails[] transactions = new TransactionDetails[dataGridView1.Rows.Count - 1];
        for (int i = 0; i < dataGridView1.Rows.Count - 1; i++)
        {
            transactions[i] = new TransactionDetails();
            transactions[i].TransactionDate = (string)dataGridView1.Rows[i].Cells[2].Value;
            transactions[i].TransactionType = (string)dataGridView1.Rows[i].Cells[3].Value;
            transactions[i].Shares = (string)dataGridView1.Rows[i].Cells[4].Value;
            transactions[i].Pershare = (string)dataGridView1.Rows[i].Cells[5].Value;
            transactions[i].TotalAmount = (string)dataGridView1.Rows[i].Cells[6].Value;
        }
        CostbasisResult result = client.Costbasis(dataGridView1.Rows[0].Cells[0].Value.ToString(), dataGridView1.Rows[0].Cells[1].Value.ToString(), transactions, false, "", "", "FIFO", true);
        return ConvertStringArrayToString(result.Details);
    }

all you need to do is call the method:

ProcessMyRequest();

and it will do the job. If you need to let the main Thread to be aware of progress, you can use the ProgressChanged event

private void bkgWorkerMyRequest_ProgressChanged(
    object sender, ProgressChangedEventArgs e)
{
    progressBar1.Value = e.ProgressPercentage;
}

in the bkgWorkerMyRequest_DoWork method you need to change the code to have

//reports a percentage between 0 and 100
bkgWorkerMyRequest.ReportProgress(i * 10); 

Remember:

alt text

You will, however get stuck when trying to Debug the method GetStuffDone as it's that kinda hard debugging multi threaded applications

So, what I do is, debug everything without workers and then apply the workers.

Works fine for me, let me know if you need any more help on this.


added

I didn't aware that you were getting the Grid in the worker, sorry, for this, just send the grid as a argument and use it, please change:

bkgWorkerMyRequest.RunWorkerAsync(dataGridView1);

string r = GetStuffDone((GridView)e.Argument);

private function string GetStuffDone(GridView dataGridView1)
balexandre
2 things:In order to get the progressbar you had//reports a percentage between 0 and 100bkgWorkerMyRequest.ReportProgress(i * 10); inside _DoWork.. however where does i come from?#2. Error 3 An object reference is required for the non-static field, method, or property 'SOAP_Client_Networth.Form1.dataGridView1'
ChrisMuench
you need to set that integer, it's you the responsible to tell the progress of the work done, .NET does not know... *10 is just to explicit remember you that's in percentage. You can't access other thread Object, you need to use Safe Thread calls. The only place that you can access the main Thread Object is in the RunWorkerCompleted. But this is other question right? ;-)
balexandre
It compiles now.However I'm getting this error when I run it.This BackgroundWorker states that it doesn't report progress. Modify WorkerReportsProgress to state that it does report progress.
ChrisMuench
change the 3 lines that I added in order to access the Grid object
balexandre
did you add the event ProgressChanged? in the image I pasted only DoWork and WorkComplete are set! as this was not your question, or at least not the one I understood.
balexandre
yup we are good to go now.
ChrisMuench
Did you understood the hole Background Work Process?
balexandre