0

I am using an int for a timer countdown in my application like this:

public partial class CardsTabPage : ContentPage
{
    public int timer1Seconds;

Later in the code there's a while look like this:

while (timer1Seconds > 0) & reposition == null)
{
    // some actions 
    await Task.Delay(100);
    timer1Seconds--;
}

The timer counts down but I also have a part of the code that responds to a button click or leaving a page that sets the value of timer1Seconds to 0 to immediately stop the while loop.

I just learned about volatile. Would this be a candidate for me to change the definition to

volatile int timer1Seconds

Also if I do change it the is that still public and just specific to the class or would that now be a variable I could access anywhere?

Alan2
  • 23,493
  • 79
  • 256
  • 450
  • 1
    The `volatile` keyword has nothing to do with access modifiers. If you declare it public it will stay public with or without volatile. Volatile - if at all - will only help if you access that field from different threads, which should be the case here (UI and Timer - but depending on the Timer class; there are different ones in the framework). Best thing to do is to [read about volatile](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/volatile), understand what it does, then decide if it applies to your setting. – Fildor Feb 06 '19 at 08:04

2 Answers2

2

The answer is no.

volatile refers to wether or not a variable can be modified by multiple threads, which you are not using as far as I can tell. More on that here.

Also, volatile doesn't affect a field's accessibilty level. That means if you replace public with volatile, the field in question would then have the standard accessibilty level.

This also means that

public volatile int x;

would be a perfectly valid combination of keywords.

hensing1
  • 187
  • 13
  • Actually there is high probability that the code uses multiple threads to access `timer1Seconds` as continuations are executed in different threads unless specific synchronization context is used which we simply don't know basing on given example. – Dmytro Mukalov Feb 06 '19 at 13:24
  • @DmytroMukalov Good point. But I guess this should give OP enough information to figure out himself whether he needs `volatile` or not. – hensing1 Feb 06 '19 at 13:30
1
  1. You must leave the public for timer1Seconds to be accessible from other classes. volatile won't do that.

  2. You should add volatile. I think in this case it won't matter, but it might. And if the code gets changed it might might matter then. In this answer https://stackoverflow.com/a/1284007/939213 you will see an example where without volatile the code will fail in release mode. This is what might happen in your code in release mode if you don't add volatile:

The compiler can optimize your code to:

for (int temporaryVar = timer1Seconds; temporaryVar > 0; temporaryVar--) 
{
   if(reposition == null)
   {
       // some actions 
       await Task.Delay(100);
       timer1Seconds = temporaryVar;
   }
}

if it thinks the for loop will be faster for some reason because it doesn't take into consideration the possibility that timer1Seconds might change out of this code. By adding volatile you tell the compiler that timer1Seconds might be changed out of this code so it won't do that optimization. I wrote "compiler" but it might be the runtime. I don't know.

I don't think this would happen in your case but we don't know for sure so you should add volatile.

123
  • 406
  • 2
  • 4