Every time timer ticks the application keep on using extra memory.
How to dispose the handle in GetActeWindowTitle() and window2?
How should i manage the memory usage for this?
my Code :
public partial class Window1 : Window
{
Window2 window2 ;
System.Windows.Forms.Timer timer1;
public Window1()
{
InitializeComponent();
timer1 = new Timer();
timer1.Interval = 900000;
timer1.Tick += new EventHandler(timer1Tick);
timer1.Start();
}
private void timer1Tick( object Sender, EventArgs e )
{
window2 = new window2Window();
if (((GetActeWindowTitle().IndexOf("Outlook") != -1) ||
(GetActeWindowTitle().IndexOf("Word") != -1)))
{
window2.Close();
}
else
{
window2.Show();
window2.Topmost = true;
}
}
private string GetActeWindowTitle()
{
const int nChars = 256;
IntPtr handle = IntPtr.Zero;
StringBuilder Buff = new StringBuilder(nChars);
handle = GetForegroundWindow();
if (GetWindowText(handle, Buff, nChars) > 0)
{
return Buff.ToString();
}
return null;
}
}
Maybe by releasing the memory that gets allocated from that Interop call referenced in the IntPtr.
Try this after using you handle in GetActeWindowTitle():
Marshal.FreeCoTaskMem(handle);
Why create new window2Window only to close it?
// window2 = new window2Window();
if (((GetActeWindowTitle().IndexOf("Outlook") != -1) ||
(GetActeWindowTitle().IndexOf("Word") != -1)))
{
// window2.Close();
}
else
{
window2 = new window2Window();
window2.Show();
window2.Topmost = true;
}
Related
I have a kinect project in wpf and it uses skeleton stream that tracks the left and right hand of its users and allows me to hover over buttons.
I tried making a new form and just copying and pasting everything so i can create a new page but it didnt work, i think i may have to reference the methods used in the main page, but i am unsure.
I want to be able to use the skeleton stream alongside the hovering method in a new window
Any help would be appreciated - i apologize if this does not make sense i am a beginner
Code
public partial class MainWindow : Window
{
private KinectSensor _Kinect;
private WriteableBitmap _ColorImageBitmap;
private Int32Rect _ColorImageBitmapRect;
private int _ColorImageStride;
private Skeleton[] FrameSkeletons;
List<Button> buttons;
static Button selected;
float handX;
float handY;
public MainWindow()
{
InitializeComponent();
InitializeButtons();
kinectButton.Click += new RoutedEventHandler(kinectButton_Click);
this.Loaded += (s, e) => { DiscoverKinectSensor(); };
this.Unloaded += (s, e) => { this.Kinect = null; };
}
//initialize buttons to be checked
private void InitializeButtons()
{
buttons = new List<Button> { button1, button2, quitButton};
}
//raise event for Kinect sensor status changed
private void DiscoverKinectSensor()
{
KinectSensor.KinectSensors.StatusChanged += KinectSensors_StatusChanged;
this.Kinect = KinectSensor.KinectSensors.FirstOrDefault(x => x.Status == KinectStatus.Connected);
}
private void KinectSensors_StatusChanged(object sender, StatusChangedEventArgs e)
{
switch (e.Status)
{
case KinectStatus.Connected:
if (this.Kinect == null)
{
this.Kinect = e.Sensor;
}
break;
case KinectStatus.Disconnected:
if (this.Kinect == e.Sensor)
{
this.Kinect = null;
this.Kinect = KinectSensor.KinectSensors.FirstOrDefault(x => x.Status == KinectStatus.Connected);
if (this.Kinect == null)
{
MessageBox.Show("Sensor Disconnected. Please reconnect to continue.");
}
}
break;
}
}
public KinectSensor Kinect
{
get { return this._Kinect; }
set
{
if (this._Kinect != value)
{
if (this._Kinect != null)
{
UninitializeKinectSensor(this._Kinect);
this._Kinect = null;
}
if (value != null && value.Status == KinectStatus.Connected)
{
this._Kinect = value;
InitializeKinectSensor(this._Kinect);
}
}
}
}
private void UninitializeKinectSensor(KinectSensor kinectSensor)
{
if (kinectSensor != null)
{
kinectSensor.Stop();
kinectSensor.ColorFrameReady -= Kinect_ColorFrameReady;
kinectSensor.SkeletonFrameReady -= Kinect_SkeletonFrameReady;
}
}
private void InitializeKinectSensor(KinectSensor kinectSensor)
{
if (kinectSensor != null)
{
ColorImageStream colorStream = kinectSensor.ColorStream;
colorStream.Enable();
this._ColorImageBitmap = new WriteableBitmap(colorStream.FrameWidth, colorStream.FrameHeight,
96, 96, PixelFormats.Bgr32, null);
this._ColorImageBitmapRect = new Int32Rect(0, 0, colorStream.FrameWidth, colorStream.FrameHeight);
this._ColorImageStride = colorStream.FrameWidth * colorStream.FrameBytesPerPixel;
videoStream.Source = this._ColorImageBitmap;
kinectSensor.SkeletonStream.Enable(new TransformSmoothParameters()
{
Correction = 0.5f,
JitterRadius = 0.05f,
MaxDeviationRadius = 0.04f,
Smoothing = 0.5f
});
kinectSensor.SkeletonFrameReady += Kinect_SkeletonFrameReady;
kinectSensor.ColorFrameReady += Kinect_ColorFrameReady;
kinectSensor.Start();
this.FrameSkeletons = new Skeleton[this.Kinect.SkeletonStream.FrameSkeletonArrayLength];
}
}
private void Kinect_ColorFrameReady(object sender, ColorImageFrameReadyEventArgs e)
{
using (ColorImageFrame frame = e.OpenColorImageFrame())
{
if (frame != null)
{
byte[] pixelData = new byte[frame.PixelDataLength];
frame.CopyPixelDataTo(pixelData);
this._ColorImageBitmap.WritePixels(this._ColorImageBitmapRect, pixelData,
this._ColorImageStride, 0);
}
}
}
private void Kinect_SkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs e)
{
using (SkeletonFrame frame = e.OpenSkeletonFrame())
{
if (frame != null)
{
frame.CopySkeletonDataTo(this.FrameSkeletons);
Skeleton skeleton = GetPrimarySkeleton(this.FrameSkeletons);
if (skeleton == null)
{
kinectButton.Visibility = Visibility.Collapsed;
}
else
{
Joint primaryHand = GetPrimaryHand(skeleton);
TrackHand(primaryHand);
}
}
}
}
//track and display hand
private void TrackHand(Joint hand)
{
if (hand.TrackingState == JointTrackingState.NotTracked)
{
kinectButton.Visibility = System.Windows.Visibility.Collapsed;
}
else
{
kinectButton.Visibility = System.Windows.Visibility.Visible;
DepthImagePoint point = this.Kinect.MapSkeletonPointToDepth(hand.Position, DepthImageFormat.Resolution640x480Fps30);
handX = (int)((point.X * LayoutRoot.ActualWidth / this.Kinect.DepthStream.FrameWidth) -
(kinectButton.ActualWidth / 2.0));
handY = (int)((point.Y * LayoutRoot.ActualHeight / this.Kinect.DepthStream.FrameHeight) -
(kinectButton.ActualHeight / 2.0));
Canvas.SetLeft(kinectButton, handX);
Canvas.SetTop(kinectButton, handY);
if (isHandOver(kinectButton, buttons)) kinectButton.Hovering();
else kinectButton.Release();
if (hand.JointType == JointType.HandRight)
{
kinectButton.ImageSource = "/Images/RightHand.png";
kinectButton.ActiveImageSource = "/Images/RightHand.png";
}
else
{
kinectButton.ImageSource = "/Images/LeftHand.png";
kinectButton.ActiveImageSource = "/Images/LeftHand.png";
}
}
}
//detect if hand is overlapping over any button
private bool isHandOver(FrameworkElement hand, List<Button> buttonslist)
{
var handTopLeft = new Point(Canvas.GetLeft(hand), Canvas.GetTop(hand));
var handX = handTopLeft.X + hand.ActualWidth / 2;
var handY = handTopLeft.Y + hand.ActualHeight / 2;
foreach (Button target in buttonslist)
{
Point targetTopLeft = new Point(Canvas.GetLeft(target), Canvas.GetTop(target));
if (handX > targetTopLeft.X &&
handX < targetTopLeft.X + target.Width &&
handY > targetTopLeft.Y &&
handY < targetTopLeft.Y + target.Height)
{
selected = target;
return true;
}
}
return false;
}
//get the hand closest to the Kinect sensor
private static Joint GetPrimaryHand(Skeleton skeleton)
{
Joint primaryHand = new Joint();
if (skeleton != null)
{
primaryHand = skeleton.Joints[JointType.HandLeft];
Joint rightHand = skeleton.Joints[JointType.HandRight];
if (rightHand.TrackingState != JointTrackingState.NotTracked)
{
if (primaryHand.TrackingState == JointTrackingState.NotTracked)
{
primaryHand = rightHand;
}
else
{
if (primaryHand.Position.Z > rightHand.Position.Z)
{
primaryHand = rightHand;
}
}
}
}
return primaryHand;
}
//get the skeleton closest to the Kinect sensor
private static Skeleton GetPrimarySkeleton(Skeleton[] skeletons)
{
Skeleton skeleton = null;
if (skeletons != null)
{
for (int i = 0; i < skeletons.Length; i++)
{
if (skeletons[i].TrackingState == SkeletonTrackingState.Tracked)
{
if (skeleton == null)
{
skeleton = skeletons[i];
}
else
{
if (skeleton.Position.Z > skeletons[i].Position.Z)
{
skeleton = skeletons[i];
}
}
}
}
}
return skeleton;
}
void kinectButton_Click(object sender, RoutedEventArgs e)
{
selected.RaiseEvent(new RoutedEventArgs(Button.ClickEvent, selected));
}
private void button1_Click(object sender, RoutedEventArgs e)
{
message.Content = "Button 1 clicked!";
}
private void button2_Click(object sender, RoutedEventArgs e)
{
message.Content = "Button 2 clicked!";
}
private void quitButton_Click(object sender, RoutedEventArgs e)
{
Application.Current.Shutdown();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
}
}
You can do this in a couple of different ways, and more ways then what is below.
You could pass a reference to the sensor itself to the new window when it is created:
public MainWindow()
{
// init code for window and Kinect
// show the second window
SecondWindow mySecondWindow = new SecondWindow(_Kinect);
mySecondWindow.Show();
// other stuff...
}
public class SecondWindow : Window
{
public SecondWindow(KinectSensor sensor)
{
// ... stuff
sensor.SkeletonFrameReady += SkeletonFrameReadyCallback;
// ... more stuff
}
}
Then subscribe to the SkeletonFrameReady callback in your second window. This might work for your situation if you are interacting with items in the seconds window.
Another way would be to create a public callback inside your second window and subscribe it to the SkeletonFrameReady event.
public MainWindow()
{
// init code for window and Kinect
// show the second window
SecondWindow mySecondWindow = new SecondWindow(_Kinect);
mySecondWindow.Show();
_Kinect.SkeletonFrameReady += mySecondWindow.SkeletonFrameReadyCallback;
}
I also notice in your code that you are firing events. If you are wanting to act on events from one window in a different window, you can subscribe to those custom events in the same mentioned above.
I am using RadTileView in my project, and by default the Tile Drag and Drop is enabled when they are in restored state
,
but I can't achieve the same functionality when 1 tile is in maximized state and all others are in minimized state
,
I think that Telerik hasn't provided this functionality in their RadTileView control. What would be the best way to achieve this, or is it possible or not?
After searching through different blogs, I came to know that this functionality is not available in Telerik Tile view out of the box, but they have added it in their wish list, You can vote for this feature here http://www.telerik.com/support/pits.aspx#/public/silverlight/2449
However as a work arround I have implemented a Behavior my self for RadTileView, which will do the required task.
public class RadTilesDragDropBehavior : Behavior<RadTileView>
{
private RadTileViewItem draggingTile { get; set; }
public TileViewDragDropBehavior()
{
// Insert code required on object creation below this point.
}
protected override void OnAttached()
{
base.OnAttached();
// Insert code that you would want run when the Behavior is attached to an object.
DragDropManager.AddDragInitializeHandler(AssociatedObject, OnDragInitialize);
DragDropManager.AddDragDropCompletedHandler(AssociatedObject, OnDragAndDropCompleted);
AssociatedObject.PreviewDragOver += MyTileView_PreviewDragOver;
}
private void OnDragInitialize(object sender, DragInitializeEventArgs args)
{
var tileView = sender as RadTileView;
var tileViewItem = args.OriginalSource as RadTileViewItem;
Point pt = Util.CorrectGetPosition((RadTileView)sender);
HitTestResult result = VisualTreeHelper.HitTest(AssociatedObject, pt);
if (result != null)
{
DependencyObject obj = result.VisualHit.ParentOfType<RadFluidContentControl>();
if (obj != null)
{
//trying to drag from Tile content area, not allowed.
return;
}
}
if (tileViewItem != null && tileView != null && tileView.MaximizedItem != null)
{
args.Data = tileViewItem;
var draggingImage = new Image
{
Source = new Telerik.Windows.Media.Imaging.RadBitmap(tileViewItem).Bitmap,
Width = tileViewItem.RestoredWidth,
Height = tileViewItem.RestoredHeight
};
if (tileView.MaximizedItem == tileViewItem)
{
args.DragVisualOffset = new Point(args.RelativeStartPoint.X - 50, args.RelativeStartPoint.Y-55);
}
args.DragVisual = draggingImage;
tileViewItem.Opacity = 0;
args.AllowedEffects = DragDropEffects.Move;
args.Handled = true;
// keep a copy of dragging tile
draggingTile = tileViewItem;
}
}
private void OnDragAndDropCompleted(object sender, DragDropCompletedEventArgs args)
{
if (args.OriginalSource.GetType() == typeof(RadTileViewItem))
{
if (AssociatedObject.MaximizedItem != null)
{
Point pt = Util.CorrectGetPosition((RadTileView)sender);
HitTestResult result = VisualTreeHelper.HitTest(AssociatedObject, pt);
if (result != null)
{
DependencyObject obj = result.VisualHit.ParentOfType<RadTileViewItem>();
if (obj != null)
{
((RadTileViewItem)obj).Position = draggingTile.Position;
draggingTile.Opacity = 100;
}
else
{
draggingTile.Opacity = 100;
}
}
else
{
draggingTile.Opacity = 100;
}
}
}
}
private void MyTileView_PreviewDragOver(object sender, System.Windows.DragEventArgs e)
{
FrameworkElement container = sender as FrameworkElement;
if (AssociatedObject.MaximizedItem != null)
{
if (container == null)
{
return;
}
double tolerance = 60;
double verticalPos = Util.CorrectGetPosition((RadTileView)container).Y;
double offset = 20;
ScrollViewer scrollViewer = AssociatedObject.FindChildByType<ScrollViewer>();
if (verticalPos < tolerance) // Top of visible list?
{
scrollViewer.ScrollToVerticalOffset(scrollViewer.VerticalOffset - offset); //Scroll up.
}
else if (verticalPos > container.ActualHeight - tolerance) //Bottom of visible list?
{
scrollViewer.ScrollToVerticalOffset(scrollViewer.VerticalOffset + offset); //Scroll down.
}
}
}
protected override void OnDetaching()
{
base.OnDetaching();
// Insert code that you would want run when the Behavior is removed from an object.
DragDropManager.RemoveDragInitializeHandler(AssociatedObject, OnDragInitialize);
DragDropManager.RemoveDragDropCompletedHandler(AssociatedObject, OnDragAndDropCompleted);
AssociatedObject.PreviewDragOver -= MyTileView_PreviewDragOver;
}
}
public static class Util
{
public static Point CorrectGetPosition(Visual relativeTo)
{
Win32Point w32Mouse = new Win32Point();
GetCursorPos(ref w32Mouse);
return relativeTo.PointFromScreen(new Point(w32Mouse.X, w32Mouse.Y));
}
[StructLayout(LayoutKind.Sequential)]
internal struct Win32Point
{
public Int32 X;
public Int32 Y;
};
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool GetCursorPos(ref Win32Point pt);
};
XAML would be like this
<telerik:RadTileView x:Name="MyTileView" ItemsSource={Binding TileItems}>
<i:Interaction.Behaviors>
<behaviors:RadTilesDragDropBehavior/>
</i:Interaction.Behaviors>
</telerik:RadTileView>
I have a class (let's call it externalClass) with a ObservableCollection<Point> channel1 inside. (the class itself does NOT implements INotify)
In the MainWindow I have a polyline binded to this externalClass.channel1 that uses a converter from ObservableCollection to PointCollection.
So from the C# I bind DataContext = externalClass; and in the XAML the polyline looks like:
<Polyline Points="{Binding channel1, Converter={StaticResource pointCollectionConverter}}" Stroke="#FF00E100" Name="line" />
I have a test function that works like that:
public void test()
{
ObservableCollection<Point> newone = new ObservableCollection<Point>();
for (int i = 0; i < debugCh1.Count; i++)
{
Point p1 = debugCh1[i];
p1.Y = p1.Y + 1;
newone.Add(p1);
}
channel1= newone;
}
If I add a breakpoint in the converter itself I can see that on start-up it is called (and actually the initial values (hard-coded) are displayed. But when I add the test function to a button .. it does nothing (the converter is not called)
Any idea idea of where the notification of the changes is being stopped ???
SOLUTION
After reading the answers and googleling a bit more I came out with the soulition. Id like to post it there for everybody else
So .. The so-called externalClass must inherit from INotifyPropertyChanged and it must implement NotifyPropertyChanged
So all and all it must be declared like that:
public class externalClass : INotifyPropertyChanged
{
....
// at some point you have your ObservableCollection<smth> as a property
public ObservableCollection<Point> channel1 { get; set; }
....
//at some point you implement NotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(string caller)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(caller));
}
}
....
//then whenever you need to fire the notification
[..]do something with channel1
NotifyPropertyChanged("channel1");
And that's all. If you add a proper binding (as the one I showed in my question) the whole set up is gonna work.. At least mine worked hehehe
Good luck! And thanks to the people that helped me !! :D
Polyline Points probably does not listen to INotifyCollectionChanged when bound. Try exposing Channel1 as a property and raise the INotifyPropertyChanged with "Channel1"
First, you need create your custom class PointCollection:
public class PointCollection : ObservableCollection<Point>
{
public PointCollection()
{
}
public PointCollection(IEnumerable<Point> points) : base(points)
{
}
}
Second, you need create custom Polyline:
public class PolylineDynamic : Shape
{
private Geometry _polylineGeometry = Geometry.Empty;
public static readonly DependencyProperty PointsProperty = DependencyProperty.Register(nameof(Points), typeof(PointCollection), typeof(PolylineDynamic), new FrameworkPropertyMetadata(PointsChanged));
private static void PointsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
((PolylineDynamic)d).PointsChanged(e);
}
private void PointsChanged(DependencyPropertyChangedEventArgs e)
{
if (e.OldValue is PointCollection oldPoints)
oldPoints.CollectionChanged -= OnPointsChanged;
if (e.NewValue is PointCollection newPoints)
newPoints.CollectionChanged += OnPointsChanged;
UpdatePolyline();
}
public PointCollection Points
{
get => (PointCollection)GetValue(PointsProperty);
set => SetValue(PointsProperty, value);
}
public static readonly DependencyProperty FillRuleProperty = DependencyProperty.Register(nameof(FillRule), typeof(FillRule), typeof(PolylineDynamic), new FrameworkPropertyMetadata(FillRule.EvenOdd));
public FillRule FillRule
{
get => (FillRule)GetValue(FillRuleProperty);
set => SetValue(FillRuleProperty, value);
}
protected override Geometry DefiningGeometry => _polylineGeometry;
private void OnPointsChanged(object sender, NotifyCollectionChangedEventArgs e)
{
switch (e.Action)
{
case NotifyCollectionChangedAction.Add:
var aPoint = e.NewItems.OfType<Point>().Single();
Add(aPoint, e.NewStartingIndex);
break;
case NotifyCollectionChangedAction.Remove:
Remove(e.OldStartingIndex);
break;
case NotifyCollectionChangedAction.Replace:
var rPoint = e.NewItems.OfType<Point>().Single();
Replace(rPoint, e.NewStartingIndex);
break;
}
}
protected void UpdatePolyline()
{
if (Points == null || Points.Count < 2)
_polylineGeometry = Geometry.Empty;
else
{
var pGeometry = GetPathGeometry();
for (var i = 0; i < Points.Count; i++)
{
if (i == 0)
continue;
var startPoint = Points[i - 1];
var point = Points[i];
var figure = new PathFigure { StartPoint = startPoint };
figure.Segments.Add(new LineSegment(point, true));
pGeometry.Figures.Add(figure);
}
}
}
private void Add(Point point, int index)
{
var pGeometry = GetPathGeometry();
if (pGeometry.Figures.Count == 0)
{
UpdatePolyline();
return;
}
if (index == Points.Count - 1)
{
var segment = new LineSegment(point, true);
var figure = new PathFigure { StartPoint = Points[index - 1] };
figure.Segments.Add(segment);
pGeometry.Figures.Add(figure);
}
else if (index == 0)
{
var segment = new LineSegment(Points[1], true);
var figure = new PathFigure { StartPoint = point };
figure.Segments.Add(segment);
pGeometry.Figures.Insert(0, figure);
}
else
{
var leftFigure = new PathFigure { StartPoint = Points[index - 1] };
leftFigure.Segments.Add(new LineSegment(point, true));
var rightFigure = new PathFigure { StartPoint = point };
rightFigure.Segments.Add(new LineSegment(Points[index + 1], true));
pGeometry.Figures.Insert(index - 1, leftFigure);
pGeometry.Figures.Insert(index, rightFigure);
}
InvalidateVisual();
}
private void Remove(int index)
{
var pGeometry = GetPathGeometry();
if (!pGeometry.Figures.Any())
{
_polylineGeometry = Geometry.Empty;
InvalidateVisual();
return;
}
if (index == Points.Count - 1 || index == 0)
pGeometry.Figures.RemoveAt(index);
else
{
var leftFigure = pGeometry.Figures[index - 1];
var rightFigure = pGeometry.Figures[index];
pGeometry.Figures.RemoveAt(index - 1);
rightFigure.StartPoint = ((LineSegment)leftFigure.Segments.Single()).Point;
}
InvalidateVisual();
}
private void Replace(Point point, int index)
{
var pGeometry = GetPathGeometry();
if (index == 0)
pGeometry.Figures[0].StartPoint = point;
else if (index == Points.Count - 1)
ReplaceSegment(pGeometry.Figures[index - 1], point);
else
{
ReplaceSegment(pGeometry.Figures[index - 1], point);
pGeometry.Figures[index].StartPoint = point;
}
InvalidateVisual();
}
private void ReplaceSegment(PathFigure figure, Point point)
{
figure.Segments.Clear();
figure.Segments.Add(new LineSegment(point, true));
}
private PathGeometry GetPathGeometry()
{
if (_polylineGeometry is PathGeometry pathGeometry)
return pathGeometry;
else
{
pathGeometry = new PathGeometry { FillRule = FillRule };
_polylineGeometry = pathGeometry;
return pathGeometry;
}
}
}
If you need more functionality, you can add more)
I want an auto logoff feature in my WPF application and have implemented it with hooks. However whenever the mouse is over the application, the performance freezes, degrades and becomes unbearably unresponsive. Once the mouse is off the window performance goes back to normal. If I turn the auto logoff off, performance is fine always, so it's definitely this causing it. Any idea how to do it different to avoid this?
private void InitializeAutoLogoffFeature()
{
//var windowSpecificOSMessageListener = HwndSource.FromHwnd(new WindowInteropHelper(this).Handle);
//if (windowSpecificOSMessageListener != null)
// windowSpecificOSMessageListener.AddHook(CallBackMethod);
//AutoLogOffHelper.LogOffTime = _viewModel.logOffTime;
//AutoLogOffHelper.MakeAutoLogOffEvent += AutoLogOffHelper_MakeAutoLogOffEvent;
//AutoLogOffHelper.StartAutoLogoffOption();
AutoLogOffHelper
}
private static IntPtr CallBackMethod(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
try
{
// Listening OS message to test whether it is a user activity
if ((msg >= 0x0200 && msg <= 0x020A) || (msg <= 0x0106 && msg >= 0x00A0) || msg == 0x0021)
{
AutoLogOffHelper.ResetLogoffTimer();
}
else
{
// For debugging purpose
// If this auto logoff does not work for some user activity, you can detect the integer code of that activity using the following line.
//Then All you need to do is adding this integer code to the above if condition.
Debug.WriteLine(msg.ToString());
}
}
catch (Exception ex)
{
MessageHelper.LogError(ex);
}
return IntPtr.Zero;
}
class AutoLogOffHelper
{
static System.Windows.Forms.Timer _timer;
public static int LogOffTime { get; set; }
public delegate void MakeAutoLogOff();
static public event MakeAutoLogOff MakeAutoLogOffEvent;
static public void StartAutoLogoffOption()
{
System.Windows.Interop.ComponentDispatcher.ThreadIdle += DispatcherQueueEmptyHandler;
}
static void _timer_Tick(object sender, EventArgs e)
{
if (_timer == null) return;
System.Windows.Interop.ComponentDispatcher.ThreadIdle -= DispatcherQueueEmptyHandler;
_timer.Stop();
_timer = null;
if (MakeAutoLogOffEvent != null)
{
MakeAutoLogOffEvent();
}
}
static void DispatcherQueueEmptyHandler(object sender, EventArgs e)
{
if (_timer == null)
{
_timer = new System.Windows.Forms.Timer
{
Interval = LogOffTime * 60 * 1000
};
_timer.Tick += _timer_Tick;
_timer.Enabled = true;
}
else if (_timer.Enabled == false)
{
_timer.Enabled = true;
}
}
static public void ResetLogoffTimer()
{
if (_timer == null) return;
_timer.Enabled = false;
_timer.Enabled = true;
}
}
Try taking your debug.writeline out - It's very slow and since you might be dealing with a lot of events, it could easily be the problem.
Failing that, have you tried using the profiler to see what's eating up resources?
I've written a WPF application that uses many Frame controls to view camera feeds. When deployed, it crashes pretty randomly (anywhere from 2 hours to 16+ hours), and I see these in the event log, consecutively:
System.AccessViolationException:
Attempted to read or write protected
memory. This is often an indication
that other memory is corrupt. at
MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG&
msg) at
System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame
frame) at
System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame
frame) at
System.Windows.Threading.Dispatcher.Run()
at
System.Windows.Application.RunDispatcher(Object
ignore) at
System.Windows.Application.RunInternal(Window
window) at
System.Windows.Application.Run(Window
window) at
System.Windows.Application.Run() at
Status_Station_client.MainClass.Main()
Faulting application status station
client.exe, version 1.0.0.0, stamp
4ad0faa5, faulting module msvfw32.dll,
version 5.1.2600.2180, stamp 41109753,
debug? 0, fault address 0x00002642.
Any ideas on how to track this down? The web pages do contain ActiveX controls, so a first guess is there's a problem there.
I haven't been able to trace this in Debug mode. Another thing I have thought of trying is swallowing the exception from the navigation call, but am unsure if this is a wise thing to do:
try
{
if (Frame1 != null)
Frame1.Source = new Uri(uriWithResolution);
}
catch (AccessViolationException ex)
{
// log message
}
EDIT: Here's some more source code, I'm stumped as to where the error is (i.e. where the exception is being thrown)
MatrixView.cs:
public partial class MatrixView : Window
{
System.Timers.Timer timer;
int pageNumber = 0;
IEnumerable<List<CameraInfo>> _cameraList;
GlobalSettings _globalSettings;
Screen _screen;
public MatrixView(List<CameraInfo> cameras, int pageFlipInterval, int camerasPerPage, GlobalSettings globalSettings, Screen screen)
{
InitializeComponent();
_globalSettings = globalSettings;
_screen = screen;
_cameraList = Partition<CameraInfo>(cameras, camerasPerPage);
this.Dispatcher.UnhandledException += new DispatcherUnhandledExceptionEventHandler(Dispatcher_UnhandledException);
displayCameras();
timer = new System.Timers.Timer(pageFlipInterval * 1000); // interval (in seconds) * 1000 ms / s
timer.Elapsed += new ElapsedEventHandler(timer_Elapsed);
timer.Enabled = true;
this.KeyUp += new System.Windows.Input.KeyEventHandler(MatrixView_KeyUp);
if (globalSettings.FullScreenOnLoad)
{
this.WindowStyle = WindowStyle.None;
}
}
void MatrixView_KeyUp(object sender, System.Windows.Input.KeyEventArgs e)
{
if (this.WindowStyle == WindowStyle.None)
{
if (e.Key == Key.F11 || e.Key == Key.Escape)
{
this.WindowStyle = WindowStyle.SingleBorderWindow;
}
}
else
{
if (e.Key == Key.F11)
{
this.WindowStyle = WindowStyle.None;
}
}
this.WindowState = WindowState.Maximized;
}
void timer_Elapsed(object sender, ElapsedEventArgs e)
{
this.Dispatcher.BeginInvoke(DispatcherPriority.Normal, new ThreadStart(delegate()
{
displayCameras();
}));
}
void Dispatcher_UnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
{
EventLog.WriteEntry("Matrix Monitor", string.Format("Unhandled exception from Matrix Dispatcher\r\nMessage: {0}\r\nSource: {1}\r\nInnerException: {2}\r\nStack Trace: {3}\r\nFull String: {4}", e.Exception.Message, e.Exception.Source, e.Exception.InnerException, e.Exception.StackTrace, e.Exception.ToString()));
e.Handled = true;
}
private void displayCameras()
{
foreach (var child in uniformGrid1.Children)
{
FrameTimer c = child as FrameTimer;
if (c != null)
{
c.Dispose();
c = null;
}
}
GC.Collect();
GC.WaitForPendingFinalizers();
uniformGrid1.Children.Clear();
List<CameraInfo> camerasInPage = _cameraList.ElementAt(pageNumber);
int numCameras = camerasInPage.Count;
int sqrtOfCameras = (int) Math.Sqrt(numCameras);
double height = _screen.Bounds.Height / sqrtOfCameras;
double width = _screen.Bounds.Width / sqrtOfCameras;
foreach (CameraInfo camera in camerasInPage)
{
uniformGrid1.Children.Add(new FrameTimer(camera, _globalSettings, height, width));
}
pageNumber++;
if (pageNumber >= _cameraList.Count<List<CameraInfo>>())
{
pageNumber = 0;
}
}
public static IEnumerable<List<T>> Partition<T>(IList<T> source, int size)
{
int remainder = source.Count % size == 0 ? 0 : 1;
for (int i = 0; i < (source.Count / size) + remainder; i++)
yield return new List<T>(source.Skip(size * i).Take(size));
}
}
FrameTimer.cs:
public partial class FrameTimer : UserControl, IDisposable
{
System.Timers.Timer timer;
string _uri;
string _noImageUrl;
bool? _successState = null;
GlobalSettings _globalSettings;
CameraInfo _camera;
Ping ping;
double _height;
double _width;
public FrameTimer(CameraInfo camera, GlobalSettings globalSettings, double height, double width)
{
InitializeComponent();
_noImageUrl = AppDomain.CurrentDomain.BaseDirectory + "noImage.jpg";
_globalSettings = globalSettings;
_camera = camera;
_height = height;
_width = width;
_uri = string.Format("http://{0}:{1}/LiveView.aspx?camera={2}", globalSettings.ServerIPAddress, globalSettings.ServerPort, camera.camName);
this.Dispatcher.UnhandledException += new DispatcherUnhandledExceptionEventHandler(Dispatcher_UnhandledException);
setUrl();
timer = new System.Timers.Timer(_globalSettings.PingInterval * 1000);
timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);
timer.Enabled = true;
}
void Dispatcher_UnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
{
EventLog.WriteEntry("Matrix Monitor", string.Format("Unhandled exception from Frame Dispatcher\r\nMessage: {0}\r\nSource: {1}\r\nInnerException: {2}\r\nStack Trace: {3}\r\nFull String: {4}", e.Exception.Message, e.Exception.Source, e.Exception.InnerException, e.Exception.StackTrace, e.Exception.ToString()));
e.Handled = true;
}
void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
this.Dispatcher.BeginInvoke(DispatcherPriority.Send, new ThreadStart(delegate()
{
setUrl();
}));
}
private void setUrl()
{
ping = new Ping();
ping.PingCompleted += new PingCompletedEventHandler(ping_PingCompleted);
videoChecks checks = new videoChecks();
string ipAddressToUse = checks.isIPInternal(_camera.camIP) ? _camera.camIP : _camera.camExtIP;
ping.SendAsync(ipAddressToUse, 1000, null);
}
void ping_PingCompleted(object sender, PingCompletedEventArgs e)
{
try
{
if (e.Reply.Status == IPStatus.Success)
{
if (_successState == null || _successState == false)
{
_successState = true;
string uriWithResolution = string.Format("{0}&res={1}x{2}&header=0", _uri, (int)_width, (int)_height);
if (Frame1 != null)
Frame1.Source = new Uri(uriWithResolution);
}
}
else
{
if (_successState == null || _successState == true)
{
_successState = false;
Image1.Source = new BitmapImage(new Uri(_noImageUrl));
}
}
}
catch (ObjectDisposedException ex)
{
Dispose();
}
finally
{
((IDisposable)sender).Dispose();
}
}
#region IDisposable Members
public void Dispose()
{
if (timer != null)
{
timer.Elapsed -= new System.Timers.ElapsedEventHandler(timer_Elapsed);
timer.Enabled = false;
timer.Dispose();
timer = null;
}
Frame1.Source = null;
if (ping != null)
{
ping.PingCompleted -= new PingCompletedEventHandler(ping_PingCompleted);
((IDisposable)ping).Dispose();
ping = null;
}
}
#endregion
}
If you look at the faulting module at the bottom your stacktrace, you will see msvfw32.dll. This is not a DLL used by WPF, so I assume it's coming from some active-x within a web page you are loading. I'm even more convinced of that due to your code implying something dealing with cameras/video and msvfw32 deals with video (its very old too!!). It's showing up in the Dispatcher loop because the Dispatcher also handles a Win32 message loop, that is ultimately used by the alleged activex.
Also, try checking for the exception here, maybe you can set the argument Handled=true