Click here to Skip to main content
15,887,135 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
I have 2 classes where Class 1 checks for value change in Class 2(Level1). This is the code in Class 1
lvl1 = new Level1();
log.Info($"[{symbol}] Level 1 initialized.");
lvl1.Request(symbol);
string level1Result = string.Empty;
while (true)
{
    level1Result = lvl1.Result;
    if (!string.IsNullOrEmpty(level1Result))
    {
        log.Info($"[{symbol}] Level 1 result 1 is {level1Result}");
        break;
    }
    else
    {
        log.Error($"[{symbol}] Level 1 result 1 is null.");
    }
    Thread.Sleep(100);
}


In class 2 I'm listening to a Socket and when data is received then I'm changing the Result variable value to "Success" and I can also see the log of the result. Even after a long time I can see that while loop is not breaking and giving me log Level 1 result 1 is null.

Code for Level1:
private void OnReceive(IAsyncResult asyn)
{
	...code that receives data
    Result = "Success";
}
	
public string Result;


I don't understand because I'm using the same instance of Level1 how can I not get value for it.

What I have tried:

I tried
public volatile string Result;

I also tried using
lock
Posted
Comments
Richard Deeming 28-Mar-24 10:17am    
There's not really enough information here to tell what the problem is. But either you're not using the same instance of Level1; or the OnReceive method is never being called; or the OnReceive method is throwing an exception before it gets to the line that assigns the Result field.

Try setting a breakpoint on the first line of the OnReceive method and debugging your code. If the breakpoint is hit, step through the method line by line to make sure it reaches the Result = "Success"; line.
Member 14623639 28-Mar-24 10:23am    
The code reaches Result = "Success"; without throwing any exception and I have also added a log log.Info($"Level 1 [{obj.Symbol}]: result changed: {Result}."); which logs Success and as you can see I'm using lvl1 = new Level1(); but still it shows Level 1 result 1 is null even after I get the log for Success.
Richard Deeming 28-Mar-24 10:52am    
Then you're almost certainly not using the same instance of Level1.

The only other option is that the compiler, runtime, or hardware is "optimising" the read of the field in such a way that it never sees the value updated by another thread. But adding volatile should have fixed that.

If you're absolutely certain that you're using the same instance in all cases, then perhaps try a different mechanism to signal that the request is complete - eg: a ManualResetEventSlim or a TaskCompletionSource. For example:
public class Level1
{
    private readonly TaskCompletionSource<bool> _result = new TaskCompletionSource<bool>();
    
    private void OnReceive(IAsyncResult asyn)
    {
	    ...code that receives data
        _result.TrySetResult(true);
    }
    
    public Task<bool> Result => _result.Task;
}

lvl1 = new Level1();
log.Info($"[{symbol}] Level 1 initialized.");
lvl1.Request(symbol);
bool result = await lvl1.Result;
log.Info($"Level 1 result 1 is {result}");
Richard Deeming 28-Mar-24 11:05am    
Based on the code in your Reddit post[^], it's almost certainly the static modifier on the m_sockLevel1 variable that's causing your problems.
Member 14623639 28-Mar-24 11:17am    
Thanks for pointing out.

1 solution

In the Level1 class change:

public string Result;


to:

private volatile string _result;

public string Result
{
    get { return _result; }
    set { _result = value; }
}


This should make sure that reads/writes to the Result are straight to memory.

If this does not work then it is likely that you are creating a new lvl1 object somewhere else in the code we can not see.

If this is the case write a constructor in Level1 that creates a GUID for that instance and check that each time you read/write the Result property.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900