Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8067495
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 5, 20262026-06-05T12:19:06+00:00 2026-06-05T12:19:06+00:00

Given an array of struct: public struct Instrument { public double NoS; public double

  • 0

Given an array of struct:

public struct Instrument
{
    public double NoS;
    public double Last;
}

var a1 = new Instrument[100];

And a threading task pool that is writing to those elements on the basis that a single element may at most be written to by two threads concurrently, one for each of the double fields (there is upstream queuing by topic effectively).

And the knowledge that double’s can be written atomically on 64 bit. (edit this mistakenly said 32 bit originally)

I need to periodically perform a calculation using all the values in the array and I’d like them to be consistent during the calc.

So I can snapshot the array with:

var snapshot = a1.Clone();

Now the question I have is with regards to the specifics of the syncronisation. If I make the members volatile, I don’t think that is going to help the clone at all, as the read/write aquire/releases are not at the array level.

Now I could have an array lock, but this will add a lot of contention on the most frequent process of writing data into the array. So not ideal.

Alternatively I could have a per row lock, but that would be a real pain as they’d all need to be aquired prior to clone, meanwhile I’ve got the writes all backing up.

Now it doesn’t really matter if the snapshot doesn’t have the very latest value if its a matter of microseconds etc, so I think I could probably get away with just having no lock. My only concern is if there could be a scenario where there isn’t a cache writeback for a sustained period. Is this something I should worry about? The writers are in TPL dataflow and the sole logic is to set the two fields in the struct. I don’t really know how or if function scope tends to correlate to cache write backs though.

Thoughts/advice?

edit: What about if I used an interlocked write to the variables in the struct?

edit2: The volume of writes is MUCH higher than the reads. There are also two seperate and concurrent services writing to the Nos & Last fields. So they could be being written simultaneously at once. This causes problems with a reference object approach for atomicity.

edit3: Further detail. Assume array is from 30-1000 elements and each element could be being updated multiple times a second.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-05T12:19:07+00:00Added an answer on June 5, 2026 at 12:19 pm

    Since Instrument contains two doubles (two 64-bit values), you can’t write it atomically (even on 64-bit machines). This means that the Clone method can never make a thread-safe copy without doing some kind of synchronization.

    TLDR; Don’t use a struct, use an immutable class.

    You would probably have more luck with a small redesign. Try using immutable data structures and concurrent collections from the .NET framework. For instance, make your Instrument an immutable class:

    // Important: Note that Instrument is now a CLASS!! 
    public class Instrument
    {
        public Instrument(double nos, double last)
        {
            this.NoS = nos;
            this.Last = last;
        }
    
        // NOTE: Private setters. Class can't be changed
        // after initialization.
        public double NoS { get; private set; }
        public double Last { get; private set; }
    }
    

    This way updating an Instrument means you have to create a new one, which makes it much easier to reason about this. When you are sure that only one thread is working with a single Instrument you are done, since a worker can now safely do this:

    Instrument old = a[5];
    
    var newValue = new Instrument(old.NoS + 1, old.Last - 10);
    
    a[5] = newValue;
    

    Since, reference types are 32-bit (or 64-bit on a 64-bit machine) updating the reference is garanteed to be atomic. The clone will now always result in a correct copy (it might lack behind, but that doesn’t seem to be a problem for you).

    UPDATE

    After re-reading your question, I see that I misread it, since one thread is not writing to an Instrument, but is writing to an instrument value, but the solution is practically the same: use immutable reference types. One simple trick for instance, is to change the backing fields of the NoS and Last properties to objects. This makes updating them atomic:

    // Instrument can be a struct again.
    public struct Instrument
    {
        private object nos;
        private object last;
    
        public double NoS
        {
            get { return (double)(this.nos ?? 0d); }
            set { this.nos = value; }
        }
    
        public double Last
        {
            get { return (double)(this.last ?? 0d); }
            set { this.last = value; }
        }
    }
    

    When changing one of the properties, the value will be boxed, and boxed values are immutable reference types. This way you can safely update those properties.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I've got a C# function that converts a byte array to a class, given
I want to access a C function that returns a struct containing double arrays
class linklist4x4 { private: struct node4x4 { double data[4][4]; node4x4 *link; }*p; public: linklist4x4();
Given two struct arrays A and B with field f1: A = struct('f1',{1,2,3}) B
This problem is taken from interviewstreet.com Given array of integers Y=y1,...,yn, we have n
Given an array of ids $galleries = array(1,2,5) I want to have a SQL
Given an array with n values, for example: $arr[] = 'ABCDEFABC'; $arr[] = 'ABCDEFDEF';
// given following array: $data = array( 0=>array( data=>object1, col=>array( 0=>array( data=>object2, col=>array( 0=>array(
Given an array like this: Array => ( [0] => 1, [1] => 2,
Given an array. How can we find sum of elements in index interval (i,

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.