TonE
TonE

Reputation: 3025

Static member variable and thread safety

I am working on an ASP.NET MVC application.

I have a ViewModel class for which I am trying to maintain a count in order to generate div ids which are used in a view:

public class ViewModel {

    private static uint instanceCount;
    private readonly uint id;

    public ViewModel(){
        id = instanceCount++;
    }

    public uint DivId
    {
        get { return id; }
    }
}

Am I correct in thinking incrementing and assigning the static member is not threadsafe and thus not safe in a web application?

What is the best way to make this safe?

Thanks.

Upvotes: 1

Views: 1444

Answers (4)

treetey
treetey

Reputation: 829

You can use System.Threading.Interlocked.Increment() method. That's will be right choice in your case. See Interlocked class for more info.

Upvotes: 0

Ben Foster
Ben Foster

Reputation: 34800

I have to ask, why you can't just handle this within your view:

public ActionResult Index() {
    var models = SomeService.GetModels(); // returns IEnumerable<YourViewModel>
    return View(models);
}

// in your view

@for (int i = 1; i == Model.Count(); i++) {
    <div id="div-@i">
        <!-- your content here -->
    </div>
}

Upvotes: 1

Matthias Meid
Matthias Meid

Reputation: 12503

You may use Interlocked.Increment instead. However, this works only with an signed integer.

Upvotes: 0

Darin Dimitrov
Darin Dimitrov

Reputation: 1038710

Am I correct in thinking incrementing and assigning the static member is not threadsafe and thus not safe in a web application?

Yes, you are correct into thinking this.

What is the best way to make this safe?

By synchronizing the access:

public class ViewModel
{
    private static uint instanceCount;
    private readonly uint id;
    private static object _syncRoot = new object();

    public ViewModel()
    {
        lock(_syncRoot)
        {
            id = instanceCount++;
        }
    }

    public uint DivId
    {
        get { return id; }
    }
}

or simply use a Guid:

public class ViewModel
{
    public ViewModel
    {
        DivId = string.Format("id_{0}", Guid.NewGuid());
    }

    public string DivId { get; private set; }
}

Upvotes: 3

Related Questions