punkouter
punkouter

Reputation: 5366

Delegate/Action is not passing value

I have a very basic understanding of using this technique so I probably and missing something simple. All I want to do is add a variable that holds the TOTAL items but the variable seems to be getting initialized back to 0 when I check it. My best guess is something is going out of scope and I am losing the value.

  1. I call a function that passes a delegate(?)

    [TestMethod]
    public void Batch_Update_Is_Working()
    {
        DataTable dt = ExcelHelper.ReadAsDataTable(pathFileName);
       EncompassBoxHelper.UpdateBoxes(ec, dt, progess => UpdateProgressBar(pi));
    }
    
  2. Inside the function I want to pass a value back.

     public static void UpdateBoxes(EncompassConnection ec, DataTable dt, Action<ProgressInfo> updateProgress)
     {
        Session s = EncompassSession.Instance(ec.Url, ec.Name, ec.Password);
    
        updateProgress(new ProgressInfo(dt.Rows.Count));
    
  3. This is where the value is stored. In ItemsTotal. All good so far.

     public class ProgressInfo
     {
         public int itemsProcessed { get; set; }
         public int itemsTotal { get; set; }
    
         public ProgressInfo()
         {
    
         }
    
         public ProgressInfo(int it)
        {
            itemsTotal = it;
        }
    }
    
  4. Now when it goes to the callback the value is 0??? pi.itemsProcessed is suppose to be 100.

    public void UpdateProgressBar(ProgressInfo pi)
    {
        pi.itemsProcessed++;
        Debug.WriteLine("Progress Info.ItemsProcessed: " + pi.itemsProcessed);
        Debug.WriteLine("Progress Info.ItemsTotal: " + pi.itemsTotal);
    
    }
    

Upvotes: 1

Views: 114

Answers (2)

jzapata
jzapata

Reputation: 1229

Looks like your pi variable is not being passed by reference so it is never really getting updated. Honestly changing a value like pi.itemsProcessed++ in your delegate function is not very common although there are ways to do it like this.

Once your delegate supports passing in a variable with the "ref" keyword, then you should be able to call your delegate with something like this:

progess => UpdateProgressBar(ref pi)

You could also make pi a static variable and then it can be updated from your delegate as well so you don't have to worry about passing it around.

Upvotes: 1

Tarec
Tarec

Reputation: 3255

Change your

EncompassBoxHelper.UpdateBoxes(ec, dt, progess => UpdateProgressBar(pi));

to

EncompassBoxHelper.UpdateBoxes(ec, dt, UpdateProgressBar);

Instead of sending the UpdateProgressBar() method to match the delegate expected in UpdateBoxes parameter, you're creating a new one by converting lambda expression, telling it to call itself specifically with a parameter of pi, instead of the one, that should be passed inside UpdateBoxes method (the new ProgressInfo(dt.Rows.Count) object).

Upvotes: 1

Related Questions