Kill my application while it's using a threaded dll call - c#

I have a structural problem resulting in an System.ObjectDisposedException with a dll.
More specifically it's a µEye Camera driver that is advised to capture data from a camera. I got two events from this camera that are fired asynchronously:
OnFrameEvent
OnSequenceEvent
The latter tells me that my capture is beeing completed and I can continue in saving my images.
This is the code that does the work:
private void onSequenceEvent(object sender, EventArgs e)
{
uEye.Camera Camera = sender as uEye.Camera;
SequenceCount++;
Camera.Acquisition.Stop();
int s32SeqID;
statusRet = Camera.Memory.Sequence.GetLast(out s32SeqID);
Invoke((MethodInvoker)delegate ()
{
lblStatus.Text = "Save Images...";
this.pbCapture.Value = 0;
});
Rectangle src = new Rectangle();
Rectangle dst = new Rectangle();
src.X = AOI_Size.X;
src.Y = AOI_Size.Y;
src.Width = AOI_Size.Width;
src.Height = AOI_Size.Height;
dst.X = 0; dst.Y = 0; dst.Width = AOI_Size.Width; dst.Height = AOI_Size.Height;
Bitmap bitmap_source = new Bitmap(MySensorInfo.MaxSize.Width, MySensorInfo.MaxSize.Height);;
Bitmap bitmap_destination = new Bitmap(dst.Width, dst.Height);;
Graphics g = Graphics.FromImage(bitmap_destination);
for (int i = 1; i < s32SeqID; i++)
{
Camera.Memory.ToBitmap(i, out bitmap_source);
g.DrawImage(bitmap_source, dst, src, GraphicsUnit.Pixel);
bitmap_destination.Save(PathToSave + i.ToString() + ".bmp");
this?.Invoke((MethodInvoker)delegate ()
{
pbOverallProgress.Value++;
pbCapture.Value++;
});
}
bitmap_source.Dispose();
g.Dispose();
this.CloseForm?.Invoke(1);
}
However - as you may expect the Invoke call will cause the ObjectDisposedException as the "Cancel"-Button is beeing pressed:
this?.Invoke((MethodInvoker)delegate ()
{
pbOverallProgress.Value++;
pbCapture.Value++;
});
Here's the code of the Cancel-Button:
private void btn_Exit_Click(object sender, EventArgs e)
{
if (MessageBox.Show("Do you really want to cancel?", "Abort", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
{
this.CloseForm?.Invoke(0);
}
}
private void UEye_Dialog_Form_CloseForm(int exitCode)
{
this?.Invoke((MethodInvoker)delegate ()
{
if (Camera != null)
{
Camera.EventFrame -= onFrameEvent;
Camera.EventSequence -= onSequenceEvent;
}
Camera?.Acquisition.Stop();
Camera = null;
ReturnCode = exitCode;
this.Close();
});
}
UEye_Dialog_Form_CloseForm(int exitCode) is a event where CloseForm is it's delegate.
I hope this was not too much information :)
This exception only occure if the image is beeing saved, not if I'm waiting for the sequence to be captured.
Sure I could pack the UI Update code within a try-catch-block or check if the forms state is Disposed/Disposing. But for my little programming skills it looks like a structural problem.
Thank you for your help :)

The tricky part is that you're doing multi-threading without synchronization.
Invoke presents one such synchronization point, which is fine. However, as you've found out, it doesn't work after the handle is disposed - this makes perfect sense; Invoke simply sends a window message to the given handle, and when the handle no longer exists there's noöne to deal with the message (not to mention what would Close (which just sends WM_CLOSE etc.) do when the window no longer exists).
Solving this is quite tricky, actually. Even if you check if the form is disposed before trying the Invoke, it might still be disposed between the check and the Invoke itself. locking would allow you to handle the synchronization, but you'd need to lock in DestroyHandle or perhaps an event like Closing - the key is to make sure that whatever signal you send is safely tied to whether Invoke is safe right now. Of course, you don't really want to use Invoke - you need BeginInvoke, otherwise you're guaranteed to have a deadlock when Invoke needs to wait for the UI thread which is currently waiting for the lock to be released. Not good :)
Being prepared for an ObjectDisposedException might be the best solution. But looking through the reference source code, it doesn't look like it's 100% correct either - it's consistent on a single thread, but you're not calling Invoke on the UI thread (obviously).

Related

Image resource release in c# application

I am doing an image processing project using Windows Forms (c#). You can see the design of my application below.
What does this app do : take the original image, create a copy and modify the copy.
My app is working well but, if I process the same original image another time without closing the app, I get an error due to (I think) the display of the modified image. I think that the display on the bottom right corner uses the resources of the image and, when I try to modify it again, the system considers that the image is already used by another program so it can't be modified.
So my question is : "How can I stop using the modified image if the user clicks on PROCESS again ?"
I tried to use the .Dispose() method but it didn't work.
Code of the c# function linked to the PROCESS button :
private async void button8_Click(object sender, EventArgs e)
{
// start the waiting animation
progressBar1.Visible = true;
progressBar1.Style = ProgressBarStyle.Marquee;
if (csI != csP)
{
MessageBox.Show("The selected profil does not match the selected image. Colorspaces are different.", "WARNING",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
else
{
pictureBox2.Image = null;
if (checkBox2.Checked == false)
{
rendered = false;
button8.Enabled = false;
await Task.Run(() => wrapper.DominantColors(trackBar1.Value, rendered));
//wrapper.DominantColors(trackBar1.Value, rendered);
}
else
{
rendering = comboBox1.Text;
string outputImage = wrapper.Link(rendering, bpc);
rendered = true;
button8.Enabled = false;
await Task.Run(() => wrapper.DominantColors(trackBar1.Value, rendered));
//wrapper.DominantColors(trackBar1.Value, rendered);
}
// re-enable things
button8.Enabled = true;
progressBar1.Visible = false;
MessageBox.Show("processing done");
Bitmap bit = new Bitmap(imgDstPath);
float WidthImg = bit.Width;
float HeightImg = bit.Height;
float alpha = WidthImg / pictureBox2.Width;
float beta = HeightImg / pictureBox2.Height;
alpha = Math.Max(alpha, beta);
float newWidthf = WidthImg / alpha;
float newHeightf = HeightImg / alpha;
int newHeight = (int)newHeightf;
int newWidth = (int)newWidthf;
pictureBox2.ClientSize = new Size(newWidth, newHeight);
pictureBox2.Image = bit;
pictureBox2.SizeMode = PictureBoxSizeMode.StretchImage;
}
}
If possible, I'd like to clear the use of the resources when I click on the process button.
Thank you in advance for your help
The basic rule is that all objects you create that implements IDisposable need to be disposed. When writing winforms apps all controls added to a forms are disposed when the form is disposed. But whenever you change things you might need to handle disposal yourself.
For example:
pictureBox2.Image = bit;
If pictureBox2.Image is already set to something you need to ensure that it is disposed.
var oldImage = pictureBox2.Image;
pictureBox2.Image = bit;
oldImage.Dispose();
I'm not sure this is the actual problem you are having, your example code is insufficient to make that determination. To discover this you need to debug your program! Start by examining your exceptions, does it fail when opening a file or some other resource? Where was that resource created? where is it disposed? Perhaps even use a memory debugger to produce a list of all objects that are alive to see if there are any suspicious objects kept around. Will disposal correctly occur if any arbitrary code throws an exception?
It is sometimes useful to check the identity of objects in the debugger, to see if it has been switched out, or see what object your breakpoint was triggered in. You can rightclick an object in the watch panel in visual studio and select "Make ObjectId", this will associate a number with the object that appears at the end of the value.
If anyone in the future wants to know the solution I found, here it is :
At the beginning of the PROCESS function I added those simple lines :
if (pictureBox2.Image != null)
{
pictureBox2.Image.Dispose();
pictureBox2.Image = null;}

Kinect Frame Arrived Asynchronous

I am looking for some help with my MultiSourceFrameArrived event in the Kinect v2 SDK.
The following is the method in question:
private async void _reader_MultiSourceFrameArrived(object sender, MultiSourceFrameArrivedEventArgs e)
{
MultiSourceFrame multiSourceFrame = e.FrameReference.AcquireFrame();
using (var colorFrame = multiSourceFrame.ColorFrameReference.AcquireFrame())
{
if (colorFrame != null)
{
_writeableBitmap.Lock();
colorFrame.CopyConvertedFrameDataToIntPtr(
_writeableBitmap.BackBuffer,
(uint)(_colorFrameDescription.Width * _colorFrameDescription.Height * _colorFrameDescription.BytesPerPixel),
ColorImageFormat.Bgra);
_writeableBitmap.AddDirtyRect(new Int32Rect(0, 0, _writeableBitmap.PixelWidth, _writeableBitmap.PixelHeight));
_writeableBitmap.Unlock();
reflectionOverlayControl.ReflectionImageSource = _writeableBitmap;
}
}
using (var bodyFrame = multiSourceFrame.BodyFrameReference.AcquireFrame())
{
if (bodyFrame != null)
{
Body body = JointHelpers.FindClosestBody(bodyFrame);
if (body != null)
{
if (body.IsTracked)
{
Dictionary<BodyComponentType, BodyComponent> bodyComponentDictionary = BuildBodyComponentDictionary(body);
foreach (BodyComponent bodyComponent in bodyComponentDictionary.Values.OrderBy(x => x.BodyComponentType))
{
bodyComponent.Generate(_writeableBitmap, _coordinateMapper, FrameType.Color, 25);
if (!_isRunningFiltering)
{
_isRunningFiltering = true;
try
{
await Task.Run(() =>
{
bodyComponent.RunFunFiltering();
});
}
finally
{
_isRunningFiltering = false;
}
}
}
reflectionOverlayControl.UpdateValues(
bodyComponentDictionary,
GetFullBodyComponent(body));
}
}
}
}
}
Now, allow me to explain:
The method runs when a particular kind of frame arrives from the Kinect, this is acquired and I can extract the ColorFrame and BodyFrame out of it in the using blocks.
The first "using" block turns the ColorFrame into a WPF WriteableBitmap (declared in the constructor) and sets a user control's ReflectionImageSource set equal to this WriteableBitmap. If this were the only using block, I would see a very smooth feed on the screen!
The second BodyFrame using determines the closest body, if it is tracked and then creates a Dictionary populated with a persons BodyComponents (hands, feet, head etc.)
The foreach loop here runs the "Generate" function on each BodyComponent, which sets a few of it's properties. For example, it sets an EncompassingRectangle property which is an Int32Rect object designed to encompass the component.
The next bit is where I need help!
The method RunFunFiltering is a heavily intensive processing method which, when run, would create a blocking statement that freezes up my UI. This would have the effect of making my color frame video feed very jumpy! This RunFunFiltering method needs to set some of the BodyComponent class's properties, such as the colour that the rectangle should be displayed, the number of white pixels in it's ReflectionImageSource and to set another writeable bitmap with the part of the first ReflectionImageSource which is contained in the rectangle.
Since this object is now complete, with all properties set (and this has been done for each of the BodyComponent's in the dictionary) I run an UpdateValues method on the view, which displays the interesting stuff in the BodyComponent class on the screen for me.
Following some advice from #sstan in this post: Async Await to Keep Event Firing
I threw in a Task.Run() block. However, this doesn't seem to be releasing my UI and I still see a jumpy image. The weird thing is in that timer example, that it works perfectly! I'm at a bit of a loss here to know what to do.
I'm a bit of a beginner with asynchronous functions but I would really like to understand your solutions. If you can provide an explanation with your code I'd be extremely grateful!
Update
I have been able to identify that the using statement which acquires the frame blocks the UI when it is placed outside of the Task.Run call.
I can't just make the whole BodyFrame using block run asynchronously because I need the first "Generate" function to always happen and not be part of the heavy processing thread. Two using blocks seems inelegant and is rather pushing my question under the carpet...
From your comment I understand the following:
You have an async function that is called when a frame arrives
If no RunFunFiltering task is running start one
If such a task is running, don't start a new one
If RunFunFiltering is finished Process the result
.
Task taskFunFiltering = null;
private async Task ProcessFrame(...)
{ // a new frame is arrived
DoSomeProcessing(...);
// only start a new run fun filtering if previous one is finished
if (taskFunFiltering == null || taskFunFiltering.IsCompleted)
{ // start a new fun filtering
// don't wait for the result
taskFunFiltering = Task.Run( () => ...);
}
}
private async Task RunFunFiltering(...)
{
// do the filtering and wait until finished
var filterResult = await DoFiltering(...);
DisplayResult(filterResult);
}

New to threading, need help making a static variable thread safe with background worker

As the title suggests, I'm new to the concept of threading and I'm learning as I go. I'm working on a program as part of a research project involving a 3D printer. I have two pieces of hardware I need to interface with: a small stage that moves up and down, and a force sensor that can detect when an object on the stage makes contact with the sensor which acts as the signal to stop moving the stage. As I said, I'm new to the whole threading concept, so I'm not even sure if I'm designing this correctly, if I should use backgroundworker or the Thread class, how to ensure thread-safety, etc.
I"m writing the program in C# using Windows Forms and decided to use two background worker controls in Visual Studio/.NET Framework, one to monitor the force sensor reading and the other to control the stage moving up and down.
It has to be fast and accurate; the stage needs to stop moving the moment a pre-defined sensor value is detected. I have two static classes, a ZStageControl static class and a ForceSensorControl static class.
ForceSensorControl has a method called UpdateSensor() which returns the current value of the force sensor, and the ZStageControl has a private static bool variable, forceDetected (set to false by default), a public property ForceDetected that gets/sets this variable, and a method called GoodToMove. GoodToMove is defined as follows:
public static bool GoodToMove()
{
if (forceDetected == true ||
Position() < MinHeight ||
Position() > MaxHeight)
return false;
else
return true;
}
My sensor update backgroundworker dowork code is defined as follows:
private void sensorUpdateBackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
double currentForceValue;
while (ForceSensorControl.IsConnected() == true)
{
if (worker.CancellationPending == true)
{
e.Cancel = true;
break;
}
else
{
try
{
currentForceValue = Double.Parse(ForceSensorControl.UpdateSensor());
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
disconnectForceSensor();
return;
}
if (currentForceValue >= forceSensorStopValue)
{
if (this.ForceDetected != null)
{
this.ForceDetected(this,
new ForceDetectedEventArgs(ZStageControl.Position(), currentForceValue));
}
}
else if (ZStageControl.ForceDetected == true)
ZStageControl.ForceDetected = false;
forceSensorValueLabel.Text = currentForceValue.ToString() + "g";
}
}
}
So as long as the sensor remains connected, continuously loop and update the force sensor vlaue. If it detects the proper force value, it fires the ForceDetected event. If it reads the value as less than the force sensor stop value, but ForceDetected is still set to true, it simply sets to false (since when the force is detected, it will stop the stage from moving and then return it to its default position, so it should reset the force detected variable).
The event code is defined as follows:
public void FormMain_ForceDetected(object sender, ForceDetectedEventArgs e)
{
if (ZStageControl.ForceDetected == true)
return;
ZStageControl.ForceDetected = true;
feedbackRichTextBox.Text += "\nForce Detected at position " +
e.ForceDetectedPosition.ToString() + " with a value of " +
e.ForceDetectedValue.ToString() + "\n";
ScrollToEndOfFeedbackBox(feedbackRichTextBox);
soundPlayer.Play();
}
The thread to move the Z-Stage up or down is defined as follows:
private void zStageMoveBackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
ZStageMoveDirections direction = (ZStageMoveDirections)e.Argument;
while (ZStageControl.IsConnected == true)
{
if (worker.CancellationPending == true)
{
e.Cancel = true;
break;
}
else
{
System.Threading.Thread.Sleep(zStageSpeed);
if (direction == ZStageMoveDirections.Down)
{
ZStageControl.MoveDown(true);
}
if (direction == ZStageMoveDirections.Up)
{
ZStageControl.MoveUp(true);
}
zStagePositionUpdateLabel.Text = ZStageControl.Position().ToString();
}
}
}
The code that calls the DoWork event for the Z-Stage move is controlled by an if statement that checks if ZStageControl.GoodToMove() is true. So while GoodToMove() returns true, the Z-Stage thread can fire.
The issue I'm having is that I'm not sure if I'm designing this right, if I'm using the backgroundworker properly, and I know my variables are not thread-safe because at certain points GoodToMove() returns true and other times it returns false, even though there is clearly no force being detected. It seems to have a mind of its own. I just know nothing about thread-safety. Should I simply use the THread class instead of the background worker, is there a certain way to ensure the forceDetected variable/GoodToMove() method operates properly across these threads?
I think your approach is inherently flawed.
You seem to be designing a system with a constantly looping monitor and then a check of that monitor when you want to execute a "move."
This is inherently problematic because you've created a race condition between your safety check operation and your move operation.
Consider this:
1 // check if move is ok -- PASS
(async) // move suddenly becomes not ok!
2 // move is executed
Instead you should think about this problem as entirely synchronous (as validation checks and executions should be entirely atomic). Whenever a move is requested you should check if it's permitted and then decide whether or not to execute.
1 // exclusive lock
2 // check if move is ok -- PASS
3 // execute move
4 // release lock

Is there anyway to know when the screen has been updated/refreshed (OpenGL or DirectX maybe?)

I currently have an application I'm writing in c# (using .NET) that requires me to start a timer as soon as a user sees an image on screen up until they respond with a key press.
Now I realise that practically this is very difficult given the monitor input lag and response time, the time the keyboard takes to physically send the message, the OS to process it, etc.
But I'm trying my best to reduce it down to mostly a constant error (the response time results will be used to compare one user to the next so a constant error isn't really an issue). However annoying hurdle is the variable caused by the monitor refresh rate, as I gather when my onPaint message is called and done with, it doesn't mean the image has actually been processed and sent from the graphics buffer?
Unfortunately time restrictions and other commitments would realistically restrict me to continuing this task in c# for windows.
So what I was wondering was if either handling all the drawing in OpenGL or DirectX or better still for me if it is possible to just using either OpenGL or DirectX to create an event when the screen is updated?
Another suggestion given to me previously was regarding V-Sync, if I switch this off is the image sent as soon as it is drawn? as opposed to sending images at a set rate synchronised to the monitor refresh rate?
You must render your graphic in a separate thread in order to:
Use vertical synchronisation to have a precise timing of the effective display of your image.
Get the precise timing of your user input (since user interface is not on the same thread than the render loop.
Initialise Direct3D to enable the VSync during render :
// DirectX example
presentParams.SwapEffect = SwapEffect.Discard;
presentParams.BackBufferCount = 1;
presentParams.PresentationInterval = PresentInterval.One;
device = new Device(...
Perform the render in a separate thread:
Thread renderThread = new Thread(RenderLoop);
renderThread.Start();
shouldDisplayImageEvent = new AutoResetEvent();
Then use the following render loop:
void RenderLoop()
{
while(applicationActive)
{
device.BeginScene();
// Other rendering task
if (shouldDisplayImageEvent.WaitOne(0))
{
// Render image
// ...
userResponseStopwatch = new Stopwatch();
userResponseStopwatch.Start();
}
device.EndScene();
device.Present();
}
}
Then handle the user input :
void OnUserInput(object sender, EventArgs e)
{
if (userResponseStopwatch != null)
{
userResponseStopwatch.Stop();
float userResponseDuration = userResponseStopwatch.ElapsedMillisecond - 1000 / device.DisplayMode.RefreshRate - displayDeviceDelayConstant;
userResponseStopwatch = null;
}
}
You now use the shouldDisplayImageEvent.Set() event trigger to display the image as needed and start the stop watch.
First enable the VSync on your application idle loop :
// DirectX example
presentParams.SwapEffect = SwapEffect.Discard;
presentParams.BackBufferCount = 1;
presentParams.PresentationInterval = PresentInterval.One;
device = new Device(...
Application.Idle += new EventHandler(OnApplicationIdle);
// More on this here : http://blogs.msdn.com/tmiller/archive/2005/05/05/415008.aspx
internal void OnApplicationIdle(object sender, EventArgs e)
{
Msg msg = new Msg();
while (true)
{
if (PeekMessage(out msg, IntPtr.Zero, 0, 0, 0))
break;
}
// Clearing render
// ...
if (displayImage)
{
// Render image
// ...
renderTime = DateTime.now();
}
device.Present();
}
With the vsync enabled, the device.Present function block until the next frame synchronisation, so if you compute the time between renderTime and the user input time and remove the display device delay + 16.67ms you should get your user response delay.

GTK+ widgets/windows being (randomly) corrupted, with what seems to be timers

I have recently implemented a scrolling text across an area of limited screen estate using a timers repeating every 100ms, and some simple string appending.
However, after this very implementation, I have come to realise that my GUI is getting randomly bugged/corrupted after a certain while. That is to say that some widgets/windows become completely white, and eventually the entire GUI turns white and unclickable.
What is weird is that there is no error debug output at all.
Having said that, I am using Mono with GTK-Sharp for the application. Does anyone have an idea or a possible clue how and why this is happening?
If not, how can I further debug this properly?
Thanks, really appreciate it.
PS: Sometimes, it takes up to 1.5 hours for the thing to start corrupting, it has random timeframes for it to start happening.
This is my the code implemented that caused this issue:
void ScrollSyncTo(object sender, System.Timers.ElapsedEventArgs e)
{
//initial check if it fits nicely alr
if (sync_to_full_txt.Length <= sync_to_max_char)
{
sync_to_timer.Stop();
return;
}
//check for pause
if (sync_to_pause >= 0)
{
sync_to_pause--;
return;
}
//check direction
int temp_psn;
string temp_str;
if (sync_to_direction)
{
temp_psn = sync_to_posn + 1;
if (sync_to_full_txt.Substring(temp_psn).Length < sync_to_max_char)
{
sync_to_pause = sync_to_break_steps;
sync_to_direction = false;
sync_to_posn = sync_to_full_txt.Length - 1;
System.GC.Collect();
return;
}
else
{
temp_str = sync_to_full_txt.Substring(temp_psn, sync_to_max_char);
}
}
else
{
temp_psn = sync_to_posn - 1;
if (temp_psn + 1 < sync_to_max_char)
{
sync_to_pause = sync_to_break_steps;
sync_to_direction = true;
sync_to_posn = 0;
System.GC.Collect();
return;
}
else
{
temp_str = sync_to_full_txt.Substring(temp_psn - sync_to_max_char + 1, sync_to_max_char);
}
}
//lets move it
sync_to.Text = temp_str;
sync_to_posn = temp_psn;
}
To program in GTK with multiple threads, you have to do a couple things to make your program thread-safe. Here is short explanation using C.
I'm more familiar with GTK in C, but I'm assuming it works the same in GTK#. So you have to call GLib.Thread.Init() and Gdk.Threads.Init() at the beginning of your program, bracket your call to Application.Run() with Gdk.Threads.Enter() and Gdk.Threads.Leave(), and also make sure any GTK and GDK calls in background threads (not GTK signal handlers) are between Gdk.Threads.Enter() and Gdk.Threads.Leave().
System.Timers.Timer callbacks come from a threadpool thread, but GTK objects can only safely be accessed from the GTK thread. I would suggest using GLib.Timeout, which runs on the GTK thread.

Categories

Resources