Hi.
C#, .Net 3.1, WPF
I want to have a WPF window that takes data from a BlockingCollection<ColorAddress>(ConcurrentQueue<ColorAddress>) continuously.
I have managed to start the window in it's own thread, but while doing this with the following code.
The thread is created as this method "RunTheGraphics" from the class "GraphicalThreadHandler"
public void RunTheGraphics()
{
VisualWorld vw = new VisualWorld(ref ags, 3840, 2160, ref logger, ref graphQueue);
vw.Show();
System.Windows.Threading.Dispatcher.Run();
while (threadIsRunning == true)
{
vw.RunGraphics();
vw.Show();
}
}
And this is the code starting it:
graphicalQueue = new BlockingCollection<ColorAddress>(new ConcurrentQueue<ColorAddress>());
graphHandler = new GraphicalThreadHandler(ref ags, ref logger, ref graphicalQueue);
graphThread = new Thread(graphHandler.RunTheGraphics);
graphThread.SetApartmentState(ApartmentState.STA);
graphThread.IsBackground = true;
graphThread.Start();
I don't know how to make the method vw.RunGraphics execute. This method is where I am looping through the queue to fetch the data contained in the object "ColorAddress".
In the above code, the code never get to anything after Dispatcher.Run(); is called. To put it in another way, how do I get the method RunGraphics to run when the Dispatcher takes over?
If there would be a way to start vw.RunGraphics with Dispatcher.Run() or something similar, it would work, but I don't know how.
So I'm stuck between not updating the graphics, which renders the window itself unusable, or to not start Dispatcher.Run(), which also makes the window unusable.
I tried calling RunGraphics from the constructor in the VisualWorld class, but then the Dispatcher also do not seem to start, and now window is ever visible.
Please advice on how to solve this.
Here is the code for the VisualWorld window:
using System;
using System.Windows;
using System.Windows.Media.Imaging;
using System.Collections.Generic;
using System.Collections.Concurrent;
using StructureLibrary;
using System.ComponentModel;
namespace EvolutionSimulator
{
public partial class VisualWorld : Window
{
private WriteableBitmap imgBmp;
private static Random rand = new Random();
private AreaGroupStructure ags;
int objectPixelSize;
int squareSize;
int areaSize;
public BlockingCollection<ColorAddress> graphHandler;
public BlockingCollection<string> logger;
string loggerPrefix;
public VisualWorld(ref AreaGroupStructure ags, int x, int y, ref BlockingCollection<string> logger, ref BlockingCollection<ColorAddress> graphHandler)
{
InitializeComponent();
this.logger = logger;
loggerPrefix = TypeDescriptor.GetClassName(this);
logger.Add(loggerPrefix + " VisualWorld is now being set up.");
this.ags = ags;
List<System.Windows.Media.Color> listOfColors = new List<System.Windows.Media.Color>();
for (int i = 0; i < 256; i++)
{
listOfColors.Add(System.Windows.Media.Color.FromArgb((byte)0, (byte)i, (byte)i, (byte)i));
}
// BitmapPalette palette = new BitmapPalette(listOfColors);
imgBmp = BitmapFactory.New(x, y);
daCanvas.Source = imgBmp;
objectPixelSize = ags.GetObjectPixelSize();
squareSize = ags.GetSquareSize();
areaSize = ags.GetAreaSize();
this.graphHandler = graphHandler;
logger.Add(loggerPrefix + " GraphHandler has been set up in VisualWorld.");
// RunGraphics();
}
public ref BlockingCollection<ColorAddress> GetQueue()
{
return ref graphHandler;
}
public void RunGraphics()
{
foreach (ColorAddress colorAddress in graphHandler.GetConsumingEnumerable())
{
logger.Add(loggerPrefix + " Now trying to dequeue the graphQueue");
ColorAddressPainter(colorAddress);
}
}
public void ColorAddressPainter(ColorAddress inCA)
{
logger.Add(loggerPrefix + " Now starting ColorAddressPainter. But will there be blood?");
ColorStruct[,] allColors = inCA.GetColorStruct();
int[] address = inCA.GetAddress();
int areaAddressX = address[0];
int areaAddressY = address[1];
int locationInAreaX = address[2];
int locationInAreaY = address[3];
int addressX = objectPixelSize * squareSize * areaSize * areaAddressX + objectPixelSize * squareSize * locationInAreaX;
int addressY = objectPixelSize * squareSize * areaSize * areaAddressY + objectPixelSize * squareSize * locationInAreaY;
for(int x = 0; x < squareSize; x++)
{
for(int y = 0; y < squareSize; y++)
{
using (imgBmp.GetBitmapContext())
{
//imgBmp.Lock();
byte[] temp = allColors[x, y].GetColor();
byte a = temp[0];
byte r = temp[1];
byte g = temp[2];
byte b = temp[3];
imgBmp.FillRectangle(addressX + x * objectPixelSize, addressY + y * objectPixelSize, addressX + x * objectPixelSize + objectPixelSize, addressY + y * objectPixelSize + objectPixelSize, System.Windows.Media.Color.FromArgb(a, r, g, b));
logger.Add(loggerPrefix + ": Now painting " + Convert.ToString(areaAddressX) + ", " + Convert.ToString(areaAddressY) + ", " + Convert.ToString(locationInAreaX) + ", " + Convert.ToString(locationInAreaY));
//imgBmp.Unlock();
}
}
}
}
}
}