What is a parent freezable? What does this error mean? - wpf

I'm getting this error:
Cannot use a DependencyObject that belongs to a different thread than
its parent Freezable
What does that even mean? Is it in English? Is the parent frozen, or is it just freezable? Any way to make a parent not freezable, if it makes the error go away?
What's happening:
I have two opengl winforms controls in a WPF app, and so far, everything's been working smoothly (I think). Now, I've added an update so that when one winform control updates the image, the other should as well. That actually used to work, and now I'm getting that error. Stepping through the code has the crash happen in random places, which leads me to believe that it's a garbage collection fault (ie, some update in another thread is creating something that's getting garbage collected, and that collection happens at a random time).
The exception is caught in the main run method, and it's an InvalidOperationException.
I'm grasping at straws here. Where do I start?
EDIT: It looks like the call that's causing the problem is this one:
if (imagePanel.InvokeRequired)
{
imagePanel.Invoke(new System.Windows.Forms.MethodInvoker(delegate{
imagePanel.ClearImages();
}));
}
else
{
imagePanel.ClearImages();
}
I'm still tracking it down; if that series of lines is commented out, the crash still happens, and the thread status has a 'just ended' thread (hence the garbage collection assumption).

OK, I've figured it out. Ordinarily, I'd just delete this question, but it was a pain to find any information about how to fix this.
The problem was a call that looked like this:
ImageBrush theBrush = new ImageBrush(new Bitmap(new Uri(...)));
if (labelStatus.Dispatcher.Thread == System.Threading.Thread.CurrentThread) {
button.background = theBrush;
}
else {
labelStatus.Dispatcher.BeginInvoke((System.Threading.ThreadStart)(delegate {
button.background = theBrush;
}));
}
But! if you do that, then the dispatcher works, and then it tries to delete the brush, but the brush itself is also apparently getting deleted in another location.
So, the take-home lesson is, if you declare an ImageBrush, then delete it in the same thread, like so:
void MyFunc(){
ImageBrush theBrush = new ImageBrush(new Bitmap(new Uri(...)));
button.background = theBrush;
}
if (labelStatus.Dispatcher.Thread == System.Threading.Thread.CurrentThread) {
MyFunc();
}
else {
labelStatus.Dispatcher.BeginInvoke((System.Threading.ThreadStart)(delegate {
MyFunc();
}));
}

Related

Detecting collision between an object inside a movie clip that is in an array vs another array of objects

Simply,
I have randomly placed and moving movie clips that will call victims And I Have another set of random Moving movie clips that have an attack animation I will call them assailants.
Victims wander randomly among Assailants an at random times the Assailants will shoot out a lightning bolt movie clip to attack the victims. It is at this point I am attempting to check for a collision between the victims and the assailants lightning Bolts.
Both types are in separate array's and I have before checked an array vs an array without a problem I have also checked static object vs an array objects internal MC without an issue. However I am Stuck when checking array vs array objects internal MC.
Code:
for(var j:int=0;j<NormalBubbleArray.length;j++){
for(var k:int=0;k<LightningStormArray.length;k++){
if(NormalBubbleArray[j].hitTestObject(LightningStormArray[k]).upbolt){
trace("hit")
NormalBubbleArray.removeAt([j]);
LightningStormArray.removeAt([k]);
}
}
}
I have also Tried
if(NormalBubbleArray[j].hitTestObject(LightningStormArray[k]).upbolt)
and 10 other ways to try and write it. Still no luck not sure if its my loop or collision detection at this point. It gives no errors when running so I assume my Syntax is Ok.
Thanks In Advance.
Update: I was tinkering with it and realized I had it wrapped in a try catch so I was not seeing the error. now my issue is this.
for(var j = 0; j<NormalBubbleArray.length;j++){
for(var k = 0; k<LightningStormArray.length;k++){
if((LightningStormArray[k]).upbolt hitTestPoint(NormalBubbleArray [j]), true){
trace("hit")
(NormalBubbleArray [j]).removeEventListener(MouseEvent.MOUSE_MOVE, ChildMouse);
NormalBubbleArray.removeAt([j]);
LightningStormArray.removeAt([k]);
}
}
}
Still Compiles but when it comes time to detect I get The following error in the output.
TypeError: Error #1006: value is not a function.
at BubblesReloaded_fla::MainTimeline/CollisionControl()
Help is appreciated.. I am still tinkering with it.
Got it !
Tricky Devil.
The debuger kept pointing to the hittest line and it had nothing to do with the actual line it hilighted but what was inside the if statment that caused the issue.
var Lstormpoints:int = 0;
for(var j = 0; j<NormalBubbleArray.length;j++){
for(var k = 0; k<LightningStormArray.length;k++){
if(LightningStormArray[k].upbolt.hitTestPoint(NormalBubbleArray [j]), true){
trace("bubble is hit")
NormalBubbleArray [j].removeEventListener(MouseEvent.MOUSE_MOVE, ChildMouse);
NormalBubbleArray [j].gotoAndPlay(10)/// was (NormalBubbleArray [j]).gotoAndPlay(10) // was causing an error
NormalBubbleArray.removeAt([j]);
LightningStormArray.removeAt([k]);
}
}
}
What threw me off was that the debugger kept pointing to the if statement as the error. What I did not catch is it was trying to tell me that it was an error inside the if statement. I figured it out after some heavy tracing I Noticed that it was detecting collision but the Bubble was not acting as if it got hit giving me the illusion that it was not detecting hit. the gotoAndPlay line animates the death and sadly that was the line with the issue.. just happy I got it going.

AS3: hitTestObject turning up null for no apparent reason

I'm currently coding a game, and in one part of the code, it's checking to see if the player is close enough to a monster in mArray for its health bar to appear. I use hitTestObject for this with var i incrementing to go through the list. However, I will randomly get this error message:
TypeError: Error #2007: Parameter hitTestObject must be non-null.
After seeing this for the first time, I put the test all under the conditional if (mArray.length > 0) to make sure the Array() was filled before even attempting the test... but it still occurs at random times. I even used trace(i) to see if it happened on a certain part of the list, but it's completely random each debug session! I know the player portion can't be null since it is on the screen at all times during the hitTest, so I'm at a loss for words right now.
The portion of code in question (nothing else is related to this except for the use of mArray[i] in different places):
for (var i:int = 0; i < mArray.length; i++) {
if (mArray.length > 0) {
trace(i); //my attempt to see if it occurred at a specific incrementation of i
if (player.hitTestObject(mArray[i])) {
mArray[i].healthBar.visible = true;
} else {
mArray[i].healthBar.visible = false;
}
}
}
Again, it works perfectly for everything all of the time except for random cases it gives me the TypeError. Is this just a hiccup in my code, is there some obvious problem that I'm overlooking, or does the code just like to throwback to 2007?
EDIT: The debug session ALWAYS points to the line with if (player.hitTestObject(mArray[i])).
It looks like for some i the mArray[i] has a null value. Either make sure this won't happen when populating the array or just add extra check in hitTestObject line like this:
if (mArray[i] && player.hitTestObject(mArray[i])) { ... }
I don't know your game's architecture but maybe it would be more convenient to move the hitTestObject test into monster class instead of checking it externally. Typical approach is to have each entity to have some kind of "update" method that is executed once in every game loop.

Retrieving Specific Active Directory Record Attributes using C#

I've been asked to set up a process which monitors the active directory, specifically certain accounts, to check that they are not locked so that should this happen, the support team can get an early warning.
I've found some code to get me started which basically sets up requests and adds them to a notification queue. This event is then assigned to a change event and has an ObjectChangedEventArgs object passed to it.
Currently, it iterates through the attributes and writes them to a text file, as so:
private static void NotifierObjectChanged(object sender,
ObjectChangedEventArgs e)
{
if (e.ResultEntry.Attributes.AttributeNames == null)
{
return;
}
// write the data for the user to a text file...
using (var file = new StreamWriter(#"C:\Temp\UserDataLog.txt", true))
{
file.WriteLine("{0} {1}", DateTime.UtcNow.ToShortDateString(), DateTime.UtcNow.ToShortTimeString());
foreach (string attrib in e.ResultEntry.Attributes.AttributeNames)
{
foreach (object item in e.ResultEntry.Attributes[attrib].GetValues(typeof(string)))
{
file.WriteLine("{0}: {1}", attrib, item);
}
}
}
}
What I'd like is to check the object and if a specific field, such as name, is a specific value, then check to see if the IsAccountLocked attribute is True, otherwise skip the record and wait until the next notification comes in. I'm struggling how to access specific attributes of the ResultEntry without having to iterate through them all.
I hope this makes sense - please ask if I can provide any additional information.
Thanks
Martin
This could get gnarly depending upon your exact business requirements. If you want to talk in more detail ping me offline and I'm happy to help over email/phone/IM.
So the first thing I'd note is that depending upon what the query looks like before this, this could be quite expensive or error prone (ie missing results). This worries me somewhat as most sample code out there gets this wrong. :) How are you getting things that have changed? While this sounds simple, this is actually a somewhat tricky question in directory land, given the semantics supported by AD and the fact that it is a multi-master system where writes happen all over the place (and replicate in after the fact).
Other variables would be things like how often you're going to run this, how large the data set could be in AD, and so on.
AD has some APIs built to help you here (the big one that comes to mind is called DirSync) but this can be somewhat complicated if you haven't used it before. This is where the "ping me offline" part comes in.
To your exact question, I'm assuming your result is actually a SearchResultEntry (if not I can revise, tell me what you have in hand). If that is the case then you'll find an Attributes field hanging off of that guy, and from there there is AttributeNames and Values. I think you'll see how it works from there if you have Values in hand, for example:
foreach (var attr in sre.Attributes.Values)
{
var da = (DirectoryAttribute)attr;
Console.WriteLine(da.Name);
foreach (var val in da.GetValues(typeof(byte[])))
{
// Handle a byte[] val ...
}
}
As I said, if you have something other than a SearchResultEntry in hand, let us know and I can revise the code sample.

Why is this method executing twice each time I call it?

I have the following method that is executing twice every time it is called:
public static void ChangeToRepository(RepositoryTextBox textBox, int repositoryNumber)
{
MessageBox.Show("you");
int indexOfLastRepository = (textBox.RepositoryCollection.Count - 1);
if (repositoryNumber > indexOfLastRepository)
{
AddTextRepositoriesThrough(textBox, repositoryNumber, indexOfLastRepository);
}
textBox.RepositoryCollection[textBox.CurrentRepositoryNumber].CurrentText = textBox.Text;
textBox.PreviousRepositoryNumber = textBox.CurrentRepositoryNumber;
textBox.CurrentRepositoryNumber = repositoryNumber;
textBox.Text = textBox.RepositoryCollection[textBox.CurrentRepositoryNumber].CurrentText;
}
The first time that the method executes, it executes all of the code except for its last line:
textBox.Text = textBox.RepositoryCollection[textBox.CurrentRepositoryNumber].CurrentText;
The second time, it executes all of the code. What's up?
When you assign to CurrentRepositoryNumber on the text box, it probably triggers an event handler that calls back to this function again. This seems likely because the property name suggests that it controls the current repository, which this method then is responsible for displaying somehow.
You might want to temporary delist, assign to the property and then re-enlist that event handler. Or maybe you need more of a redesign to get the responsibilities clear - often with GUI frameworks that is hard to do, and the simplest option is to just delist, assign, re-enlist, with this kind of pattern:
textBox.TextChange -= YourHandler;
textBox.Text = newValue;
textBox.TextChange += YourHandler;

What is wrong with my X11 code?

I am attempting to get the X Window at a certain location on screen. When I asked people for a function to do this, they said you would just call XQueryTree recursively.
This is the code snippet which I think is somehow wrong. When I debug it, it seems to work perfectly. The only problem is that the output it gives seems a little strange. When I do XQueryTree on the root window, I get hundreds of children, when I only have five or so open. Also, it seems to think that there is a top-level window somewhere where there simply isn't one, and returns it as a result. No matter how I move my actual windows around, XQueryTree seems to indicate that there is another window on top of my windows (not covering the entire screen.) When I look at where it says the window is, it is at some arbitrary point on my desktop.
If this is of any help:
The display is from XOpenDisplay(NULL), and the root window I originally pass it is XDefaultRootWindow(display). I am running gnome under debian with metacity.
point getwindowatloc(Display * display, Window root, jint x, jint y) {
Window returnedroot;
Window returnedparent;
Window * children;
unsigned int numchildren;
XQueryTree(display,root,&returnedroot,&returnedparent,&children, &numchildren);
XWindowAttributes w;
int i;
for(i=numchildren-1; i>=0; i--) {
XGetWindowAttributes(display,children[i],&w);
if(x>=w.x && x<=w.x+w.width && y>=w.y && y <= w.y+w.height) {
point result={w.x,w.y};
XFree(children);
return result;
} else {
point result=getwindowatloc(display,children[i],x-w.x,y-w.y);
if(result.x!=INT_MAX) {
result.x+=w.x;
result.y+=w.y;
XFree(children);
return result;
}
}
}
if(children) {
XFree(children);
}
return notfound;
}
Thanks!
EDIT: For anyone who is searching for similar information: I ended up looking into the source of xwininfo. The key function is Find_Client in dsimple.c, which somehow ignores window managers to get the window you are actually looking for. If you want to look into subwindows, this is some code I added to Select_Window in dsimple.c which will recursively look inside subwindows, using XTranslateCoordinates.
Window child;
do {
XTranslateCoordinates(dpy,target_temp,target_win,x,y,&x,&y,&child);
target_temp=target_win;
target_win=child;
} while(target_win);
return target_temp;
I think what you want to do is query the root window's _NET_CLIENT_LIST property. This will produce a list of Window IDs for all client windows, excluding all of the "virtual" windows created by the window manager. Most window managers apparently support _NET_CLIENT_LIST, but you can also query whether or not any given feature is supported.
Your code looks right (I haven't tested it), and the results you describe don't seem strange at all. Metacity (and other X window managers) will create lots of windows around and near the application-owned windows to show the window title, borders and other decorations.
Try running your test with some simpler window manager like TVM (or even none at all). TVM should create a lot less windows than current window managers. This should make things easier to understand.
Usually, however, it's a bad idea to fight against the window manager. Can't you solve your problem in a higher level way withour having to use xlib directly?

Resources