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.
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
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
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
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
What's wrong with using a synchronization object like a mutex or semaphore?
Offline
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
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
[ Started around 1732731122.2906 - Generated in 0.096 seconds, 12 queries executed - Memory usage: 1.47 MiB (Peak: 1.61 MiB) ]