How to set counter in main flow from called delegate function

Suraj 1 Reputation point
2021-04-02T16:01:17.01+00:00

Hi,

Am having some trouble getting this going - here's the code. Need the delegate function call triggered in StartLockDown() to be able to set the lockDownStartedCount in the code below. Not sure if this is possible. Thought to reach out.
[Test]
public void LockDownMethods_RaisingTheEvents()
{
int lockDownStartedCount = 0, lockDownEndedCount = 0;

        _lockDownManager.LockDownEnded += (sender, args) => lockDownEndedCount++;
        _lockDownManager.LockDownStarted += (sender, args) => lockDownStartedCount++;


        Assert.AreEqual(0, lockDownStartedCount);
        Assert.AreEqual(0, lockDownEndedCount);



        _lockDownManager.StartLockDown();
        Assert.AreEqual(1, lockDownStartedCount);
        Assert.AreEqual(0, lockDownEndedCount);


        _lockDownManager.StartLockDown();
        Assert.AreEqual(1, lockDownStartedCount);
        Assert.AreEqual(0, lockDownEndedCount);


        _lockDownManager.EndLockDown();
        Assert.AreEqual(1, lockDownStartedCount);
        Assert.AreEqual(1, lockDownEndedCount);

        _lockDownManager.EndLockDown();
        Assert.AreEqual(1, lockDownStartedCount);
        Assert.AreEqual(1, lockDownEndedCount);

        _lockDownManager.StartLockDown();
        Assert.AreEqual(2, lockDownStartedCount);
        Assert.AreEqual(1, lockDownEndedCount);
    }

Currently - I have the StartLockDown method in lockdownmanager method as

public void StartLockDown()
{

          LockDownStarted = setCounter();
        LockDownStarted.Invoke(this, EventArgs.Empty); // think something needs to change here - like pass the main counter value to setCounter - I tried deriving from EventArgs and adding an int field, that didn't work either
      }

public virtual void setCounter(object sender, EventArgs e)
//{
// this method is incorrect, something needs to happen here...
// Console.Write(" in setAccountLockdown----start####");

    //    //if (e.counter == 0)
    //    //    e.counter = 1;


    //}
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,260 questions
0 comments No comments
{count} votes

6 answers

Sort by: Newest
  1. Suraj 1 Reputation point
    2021-04-02T21:25:26.207+00:00

    Hi Karen,

    Thank you for your response. I can see your solution working too. And you're right, it requires the Whatever class being passed from the main calling program and using this to set sender.startLockDown = <whatever value we want to>

    and hopefully this should reflect in the main code.

    I haven't tested this yet. There are a bunch of constraints that am forced to get the solution for. My Handler is a no param Event Handler so am not sure how this would work without a param for eventdata being passed to the delegate.

    Maybe the question is flawed. I don't know. I was given this as a part of a test - maybe it does requires a parameter to be passed to the EventHandler/delegate.

    Good to know though. This is new for me and I am learning reading all the comments on here.

    Thank you all,
    Suraj


  2. Karen Payne MVP 35,036 Reputation points
    2021-04-02T19:32:18.14+00:00

    Look at the following which has a class project and a unit test project.

    The code is a working conceptual test example that does not match up to your code but the point should be apparent

    Test class

    using System;  
    using System.Collections.Generic;  
    using ManagerLibrary;  
    using ManagerUnitTestProject.Base;  
    using Microsoft.VisualStudio.TestTools.UnitTesting;  
      
    namespace ManagerUnitTestProject  
    {  
        [TestClass]  
        public class UnitTest1 : TestBase  
        {  
            [TestInitialize]  
            public  void Init()  
            {  
      
                if (TestContext.TestName == "TestMethod1")  
                {  
                    Example.OnProcessingCompletedEvent += OnProcessingCompletedEvent;  
                }  
                  
            }  
            /// <summary>  
            /// Creates an new instance of TestContext used above  
            /// </summary>  
            /// <param name="testContext"></param>  
            [ClassInitialize()]  
            public static void MyClassInitialize(TestContext testContext)  
            {  
                TestResults = new List<TestContext>();  
            }  
            [TestMethod]  
            public void TestMethod1()  
            {  
                var example = new Example() {StartValue = 1, EndValue = 10};  
                example.DoWork();  
      
                Assert.IsTrue(StarterValue == 1 && EnderValue == 10);  
                  
            }  
            private void OnProcessingCompletedEvent(WhatEver sender)  
            {  
                StarterValue = sender.StartLockDownCount;  
                EnderValue = sender.EndLockDownCount;  
            }  
        }  
    }  
    

    Test base

    using System.Collections.Generic;  
    using Microsoft.VisualStudio.TestTools.UnitTesting;  
      
    namespace ManagerUnitTestProject.Base  
    {  
        public class TestBase  
        {  
            protected TestContext TestContextInstance;  
            public TestContext TestContext  
            {  
                get => TestContextInstance;  
                set  
                {  
                    TestContextInstance = value;  
                    TestResults.Add(TestContext);  
                }  
            }  
      
            public static IList<TestContext> TestResults;  
      
            public int StarterValue { get; set; }  
            public int EnderValue { get; set; }  
      
      
        }  
    }  
    

    Class project
    84026-f1.png

    0 comments No comments

  3. Suraj 1 Reputation point
    2021-04-02T18:21:41.12+00:00

    Hi Viorel-1,

    I think your solution would work. However, am asked not to modify the main calling code....as in the main [Test] method

    [Test]
    public void LockDownMethods_RaisingTheEvents()
    {
    int lockDownStartedCount = 0, lockDownEndedCount = 0;

         _lockDownManager.LockDownEnded += (sender, args) => lockDownEndedCount++;
         _lockDownManager.LockDownStarted += (sender, args) => lockDownStartedCount++;
         Assert.AreEqual(0, lockDownStartedCount);
         Assert.AreEqual(0, lockDownEndedCount);
         _lockDownManager.StartLockDown();
         Assert.AreEqual(1, lockDownStartedCount);
         Assert.AreEqual(0, lockDownEndedCount);
         _lockDownManager.StartLockDown();
         Assert.AreEqual(1, lockDownStartedCount);
         Assert.AreEqual(0, lockDownEndedCount);
         _lockDownManager.EndLockDown();
         Assert.AreEqual(1, lockDownStartedCount);
         Assert.AreEqual(1, lockDownEndedCount);
         _lockDownManager.EndLockDown();
         Assert.AreEqual(1, lockDownStartedCount);
         Assert.AreEqual(1, lockDownEndedCount);
         _lockDownManager.StartLockDown();
         Assert.AreEqual(2, lockDownStartedCount);
         Assert.AreEqual(1, lockDownEndedCount);
     }
    
    0 comments No comments

  4. Viorel 112.2K Reputation points
    2021-04-02T18:17:17.547+00:00

    Maybe add a new event — InitLockDown — like this:

    lockDownManager.InitLockDown += (sender, args) => lockDownStartedCount = 0;
    

    Your setCounter will invoke this event.

    0 comments No comments

  5. Suraj 1 Reputation point
    2021-04-02T18:05:17.153+00:00

    Hi Karen,

    Thank you for the response. I think we might be missing one piece here, its not so much about as a lockdown counter. Rather it is getting the called delegate function to update a counter variable in the main calling code. Example - the main calling code has

    _lockDownManager.LockDownStarted += (sender, args) => lockDownStartedCount++;

    Assume value of lockDownStartedCount is 0.

    Now when we call

    lockDownManager.StartLockDown();
    Assert.AreEqual(1, lockDownStartedCount); // this one will now return true since StartLockDown method invokes the delegate also increasing the value of lockDownStartedCount by 1 as per the definition above _lockDownManager.LockDownStarted += (sender, args) => lockDownStartedCount++;

    public void StartLockDown()
    {

           LockDownStarted = setCounter();
         LockDownStarted.Invoke(this, EventArgs.Empty); 
       }
    

    public virtual void setCounter(object sender, EventArgs e)
    //{
    //Do something here
    and then reset lockDownStartedCount back to zero

     //}
    

    What we are trying to achieve is reset the value of lockDownStartedCount in the main calling code to 0 from setCounter().

    Hope that helps to understand the issue.

    Thanks

    0 comments No comments