Official Everybody Edits Forums

Do you think I could just leave this part blank and it'd be okay? We're just going to replace the whole thing with a header image anyway, right?

You are not logged in.

#1 2016-03-03 17:33:42, last edited by Hexagon (2016-03-03 17:34:44)

Hexagon
Member
Joined: 2015-04-22
Posts: 1,213

Reading from an array that's being written to

I'm trying to read a DatabaseObject[] array as it's being written to by playerio. I can wait, but it takes too long, and I could be doing another task in the background. Since these types are arrays can't be enumerated over nicely (they'll throw an exception) and if I read a value that's being written to I could get garbage data.

I know the size of the final array beforehand, so I'm thinking if I initialize all of the values to null, then check for null to see if I've reached the last item in the array. However, I don't think it's atomic and so I might get half an object in it.

Possibly I could read until the null, then backtrack two values (because maybe the first array value would have saved before the next one was generated.)

I could decompile PlayerIO and access the implementation where it's adding the elements to the array, but it looks very very complicated.

How do I read from an array that's being written to, and to wait while the other values are being created, then read those as soon as I can, ensuring that the values are initialized? This is the code I have so far, which seems to work with the example, but I'm not sure if it is threadsafe or if there is a better way.

using System;
using System.Threading;

namespace ArrayThreadTest
{
    class DatabaseObject
    {
        public bool initialized = false;
        public string notchanging = "orange";
    }

    class Program
    {
        static DatabaseObject[] test = new DatabaseObject[5];
        static int MAX_ITEMS = 5;

        static void DoWork()
        {
            for (int i = 0; i < MAX_ITEMS; i++)
            {
                test[i] = new DatabaseObject();
                test[i].initialized = true;
                Thread.Sleep(1000);
            }

        }
        static void Main(string[] args)
        {
            Thread workerThread = new Thread(DoWork);
            workerThread.Start();

            for (int i = 0; i < MAX_ITEMS; i++)
            {
                if (test[i] != null)
                {
                    Console.WriteLine(test[i].initialized);
                } else
                {
                    Thread.Sleep(10);
                    i--;
                }
            }

        }
    }
}

Offline

#2 2016-08-11 05:46:41

Swarth100
Member
Joined: 2015-07-18
Posts: 305

Re: Reading from an array that's being written to

There are a number of ADTs that do the job;

If possible I'd use a Queue<E>, checking for a false isEmpty() before deQueueing.

Offline

#3 2016-08-11 13:37:08

Hexagon
Member
Joined: 2015-04-22
Posts: 1,213

Re: Reading from an array that's being written to

Spinastar wrote:

There are a number of ADTs that do the job;

If possible I'd use a Queue<E>, checking for a false isEmpty() before deQueueing.

Is there a way I can cast the DatabaseObject array to a queue when it's being filled? It seems like when I try to read from the array, there's nothing, then all of a sudden all of the objects come in.

Offline

#4 2016-08-11 13:55:12, last edited by Swarth100 (2016-08-11 14:33:42)

Swarth100
Member
Joined: 2015-07-18
Posts: 305

Re: Reading from an array that's being written to

So,

I believe you can have a Queue of DatabaseObjects:

Queue<DatabaseObject> test = new Queue<DatabaseObject>()

Now, Queues work differently from arrays, so you might want to google for the .NET documentation for the specific methods.

In Java you can add to a Queue in the following way:

DatabaseObject temp = new DatabaseObject;
temp.initialised = true;
test.enqueue(temp);

To retrieve information from a Queue you can:
peek() : look at first object without taking it out from the queue
dequeue() : returns the first object of the Queue and deletes it from te queue

A usual iteration method (in Java) would be the following:

while (!test.isEmpty()) {
  System.out.println(test.dequeue().initialised); // equivalend form of Console.Writeline
}

EDIT:

.NET Documentation for a Queue: https://msdn.microsoft.com/en-us/librar … .110).aspx

EDIT2:

using System;
using System.Threading;

namespace ArrayThreadTest
{
    class DatabaseObject
    {
        public bool initialized;
        public string notchanging;

       public DatabaseObject() {
         initialized = false;
         notchanging = "orange";
      }
    }

    class Program
    {
        static MAX_ITEMS = 5;

        Queue<DatabaseObject> test = new Queue<DatabaseObject>();

        static void DoWork()
        {
            for (int i = 0; i < MAX_ITEMS; i++)
            {
                DatabaseObject temp = new DatabaseObject();
                temp.initialized = true;
                test.Enqueue(temp);
                Thread.Sleep(1000);  // Do you need Thread.Sleep 100%?
            }

        }
        static void Main(string[] args)
        {
            Thread workerThread = new Thread(DoWork);
            workerThread.Start();

            /*for (int i = 0; i < MAX_ITEMS; i++)
            {
                if (test[i] != null)
                {
                    Console.WriteLine(test[i].initialized);
                } else
                {
                    Thread.Sleep(10);
                    i--;
                }
            }*/

            while (true) {
                if (test.Count != 0) {
                    Console.Writeline(test.Dequeue().initialised);
                }
                else {
                    Thread.Sleep(10); // I really don't like Thread.Sleep on main
                }
                //Note the while loop will never exit. Consider adding a counter for the number of DatabaseObjects found. If the counter gets greater than MAX_ITEMS then the loop breaks.
           }


        }
    }
}

Offline

#5 2016-08-11 16:46:25

Kaslai
Official Caroler
From: SEAͩT̓͑TLͯͥͧͪ̽ͧE͑̚
Joined: 2015-02-17
Posts: 787

Re: Reading from an array that's being written to

What's wrong with using a synchronization object like a mutex or semaphore?

Offline

Wooted by:

#6 2016-08-11 18:51:24

Swarth100
Member
Joined: 2015-07-18
Posts: 305

Re: Reading from an array that's being written to

Kaslai wrote:

What's wrong with using a synchronization object like a mutex or semaphore?

Would work too, it only depends on what else you want to do while the backgroundWorker loads the data.

Offline

#7 2016-08-11 18:53:25

den3107
Member
From: Netherlands
Joined: 2015-04-24
Posts: 1,025

Re: Reading from an array that's being written to

Personally found this.
It also contains Spinastar's queue, but as a "ConcurrentQueue".
His Queue object is guaranteed only thread safe as a "public static", just like arrays (maybe just add public and you're done?).

I also once heard (I think it was from a DLL) about an object type (I think it was a list)  to which you could subscribe on, with ~3 different types of events, maybe google for something like that?.

Offline

Wooted by:
den31071470938005618301

Board footer

Powered by FluxBB

[ Started around 1732400339.4341 - Generated in 0.081 seconds, 12 queries executed - Memory usage: 1.47 MiB (Peak: 1.61 MiB) ]