|
The most common way for this to happen is for an infinite recursion or loop to happen, e.g. a method calling itself (or calling itself via other method(s)) in such a way that the loop never ends. There is a stack object used by the .net framework when it executes your code (called the call execution stack), this has a finite size. Normally you enter a method (the call is pushed on the stack) and when the method exits the method is removed (popped off) from the stack. When infinite looping happens the method (or methods if a calls b calls c calls a etc) is repeatedly popped onto the stack filling it, then it overflows. As the stack is large this normally takes a few seconds though it can take even longer depending on your intervening code.
One problem with this is that the stack overflow exception doesn't necessarily happen where the actual problem is, so you might not have included the recursive code needed so we can help you in your problem.
I suggest two options:
1) Run the code until the error occurs, then open the stack trace window[^]. You'll see the calls made by your code and by reading through this you'll see the loop and hopefully where you need to break out of it.
2) Put a breakpoint on the code where you are getting the failure, then step through. At some point you'll loop round (hopefully quickly!) again you'll need to decide where you want to break out.
I'd try these two first, the first option is quicker though if you can't spot your problem then the second option will be clearer. There is a possibility that images.Dispatcher.Invoke (ert, new object [] {images, url}); is causing the loop, if ert is either directly or indirectly recursive. The other thing that might be the case (though unlikely) is that you have an non call-stack which is filling, but even this is likely to be filled by an infinite loop.
[Edit]
Me use INglish good and tipe weLL
“Education is not the piling on of learning, information, data, facts, skills, or abilities - that's training or instruction - but is rather making visible what is hidden as a seed” “One of the greatest problems of our time is that many are schooled but few are educated”
Sir Thomas More (1478 – 1535)
|
|
|
|
|
hello I tried your solution, I put a break-point and I noticed that IF is the cycle that makes me run any code inifinite times.
public void setImage(Image images,string url)
{
if (images.Dispatcher.CheckAccess())
{
MessageBox.Show("ciao");
Del ert = new Del(setImage);
images.Dispatcher.Invoke(ert, new object[] { images, url });
BitmapImage img = new BitmapImage();
img.BeginInit();
img.UriSource = new Uri(url);
img.EndInit();
images.Source = img;
}
else
{
images.Dispatcher.BeginInvoke(new Del(setImage), DispatcherPriority.Normal,
new object[] { images, url });
}
}
public void StreamImg()
{
while (true)
{
var date = DateTime.Today.Hour;
setImage(image1, @"http://ipaddress/jpg/image.jpg" + "?" + date);
Thread.Sleep(1000);
}
}
|
|
|
|
|
public void setImage(Image images,string url)
{
if (images.Dispatcher.CheckAccess())
{
MessageBox.Show("ciao");
Del ert = new Del(setImage);
images.Dispatcher.Invoke(ert, new object[] { images, url });
}
else
{
images.Dispatcher.BeginInvoke(new Del(setImage), DispatcherPriority.Normal, new object[] { images, url });
}
}
See the comment parts I've made in the stripped down version of your code. This is the problem, in both branches of the if/else you recursively try to call the method.
I think you need to do the following:
public void setImage(Image images,string url)
{
if (images.Dispatcher.CheckAccess())
{
MessageBox.Show("ciao");
BitmapImage img = new BitmapImage();
img.BeginInit();
img.UriSource = new Uri(url);
img.EndInit();
images.Source = img;
}
else
{
images.Dispatcher.BeginInvoke(new Del(setImage), DispatcherPriority.Normal,
new object[] { images, url });
}
}
Was should happen is setImage is called, if it is on the Dispatcher, fine, the UI is updated in the if block and the method exits. If the call isn't on the dispatcher the else block is executed, setImage calls itself on the dispatcher asychronously. When this call is executed, the if block is executed, the UI updated and the method exits (also exiting the call to setImage on the non-dispacther thread).
“Education is not the piling on of learning, information, data, facts, skills, or abilities - that's training or instruction - but is rather making visible what is hidden as a seed” “One of the greatest problems of our time is that many are schooled but few are educated”
Sir Thomas More (1478 – 1535)
|
|
|
|
|
Keith, Thank you very much, with your solution the error disappears... thanks for your patience!!
|
|
|
|
|
No problem!
“Education is not the piling on of learning, information, data, facts, skills, or abilities - that's training or instruction - but is rather making visible what is hidden as a seed” “One of the greatest problems of our time is that many are schooled but few are educated”
Sir Thomas More (1478 – 1535)
|
|
|
|
|
Ehm sorry, but I tried again and I noticed that no longer enters into the cycle without those commands, how i do?
|
|
|
|
|
You going to have to put breakpoints on and check, the method should be entered at least once when streamImage calls it. You shouldn't be "cycling" as such, the code should be called once, go into the "else" block which calls the method once under the dispatcher thread (entering the if block and ending). If you need to loop then I don't understand the purpose of your code.
If you are entering the "else" block without going to the "if" It could be that you don't want the asynchronous BeginInvoke and you need a straight Invoke instead, but I don't know why you chose the async method in the first place. It may be the dispatcher is being destroyed before the async method is called, I really can't remember if this is possible, or if an exception is thrown if it does. It could also be that the Dispatcher is running something on a higher priority that is blocking your opertation, but I think this is less likely.
Can't be much more help than that I'm afraid.
“Education is not the piling on of learning, information, data, facts, skills, or abilities - that's training or instruction - but is rather making visible what is hidden as a seed” “One of the greatest problems of our time is that many are schooled but few are educated”
Sir Thomas More (1478 – 1535)
|
|
|
|
|
the complete code is the following:
public partial class MainWindow : Window
{
Thread newtrd;
public MainWindow()
{
InitializeComponent();
}
public delegate void Del(Image images, string url);
public void setImage(Image images,string url)
{
if (images.Dispatcher.CheckAccess())
{
BitmapImage img = new BitmapImage();
img.BeginInit();
var date = DateTime.Today.Hour;
img.UriSource = new Uri(url + "?" + date);
img.EndInit();
img.Freeze();
images.Source = img;
}
else
{
images.Dispatcher.BeginInvoke(new Del(setImage), DispatcherPriority.Normal,
new object[] { images, url });
}
}
public void StreamImg()
{
while (true)
{
try
{
setImage(image1, @"http://ipaddress/jpg/image.jpg");
}
catch (Exception x)
{
MessageBox.Show(x.Message.ToString() + "\n Chiudere il Programma dal pulsante Exit");
}
Thread.Sleep(500);
}
}
private void button1_Click(object sender, RoutedEventArgs e)
{
newtrd = new Thread(new ThreadStart(StreamImg));
newtrd.IsBackground = true;
newtrd.Start();
}
private void button2_Click(object sender, RoutedEventArgs e)
{
if (newtrd.IsAlive)
{
newtrd.Abort();
}
this.Close();
}
}
}
I use delegates to overcome the problems of access to the thread
|
|
|
|
|
Here's a little trick for you - there's no need to do cross thread access on a BitmapImage . As this class inherits from Freezable , you can simply call Freeze on the BitmapImage object before you assign it to images.Source . Your code could end up like this:
public void StreamImage()
{
while (true)
{
var date = DateTime.Today.Hour;
string url = @"http://ipaddress/jpg/image.jpg?" + date;
BitmapImage image = new BitmapImage();
image.BeginInit();
image.UriSource = new Uri(url);
image.EndInit();
image.Freeze();
images.Source = image;
}
}
|
|
|
|
|
i tried this solution, but I got another error: Unable to lock this Freezable.
|
|
|
|
|
Ah yes. You're getting this because your Uri is still downloading the stream. If you hook into the DownloadComplete event on the BitmapImage, you can freeze the image at that point.
|
|
|
|
|
Yes, i want the stream, the live stream of the my Ip-Cam...the only solution is to use the Thread... n fact, I used it with the windows form and didn't give me no error..
|
|
|
|
|
So the solution I mentioned (hooking the DownloadComplete event) will sort this for you.
|
|
|
|
|
thanks for the reply, but it does not work the same, whether the method that freeze the video stream ..
|
|
|
|
|
What do you mean by it doesn't work the same? What does your code look like now?
|
|
|
|
|
Now, my code show me only one image, and not the video stream.. and if i use freeze method, the code generate the error! if you want i post my code..
|
|
|
|
|
If you don't post your code, I can't see what's wrong with it.
|
|
|
|
|
you're right.. XD
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
DispatcherTimer timer1 = new DispatcherTimer();
public BitmapImage StreamImage()
{
while (true)
{
var date = DateTime.Now.Hour;
string url = @"http://ipaddress/jpg/image.jpg?" + date;
BitmapImage image = new BitmapImage();
image.BeginInit();
image.UriSource = new Uri(url);
image.EndInit();
image.DownloadCompleted += new EventHandler(image_DownloadCompleted);
return image;
}
}
public void image_DownloadCompleted(Object sender, EventArgs args)
{
image1.Source = StreamImage();
}
private void button1_Click(object sender, RoutedEventArgs e)
{
timer1.Interval = new TimeSpan(0, 0, 5);
timer1.Tick += new EventHandler(image_DownloadCompleted);
timer1.Start();
}
}
this is all the code....
|
|
|
|
|
The problem is that you are returning out of your while loop, so you will only get 1 image. Try this instead:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
DispatcherTimer timer1 = new DispatcherTimer();
public void StreamImage()
{
while (true)
{
var date = DateTime.Now.Hour;
string url = @"http://ipaddress/jpg/image.jpg?" + date;
BitmapImage image = new BitmapImage();
image.DownloadCompleted += (s,e) =>
{
image.Freeze();
image1.Source = image;
}
image.CacheOption = BitmapCacheOption.OnLoad;
image.BeginInit();
image.UriSource = new Uri(url);
image.EndInit();
}
}
public void StartStreaming(Object sender, EventArgs args)
{
StreamImage();
}
private void button1_Click(object sender, RoutedEventArgs e)
{
timer1.Interval = new TimeSpan(0, 0, 5);
timer1.Tick += StartStreaming;
timer1.Start();
}
}
|
|
|
|
|
i tried your solution, but i've not ouput... the code doesn't show the video stream, but also the image..it always load.....but then a few minuts it show me this error:
Exception of type 'System.OutOfMemoryException'.
|
|
|
|
|
Hoo boy - I've just reexamined the rest of your code. Remove the while part, and let the timer take care of itself. Basically, you have a timer firing, and in the time it's firing, you're creating while loops that never end. Drop the while loop and set the timer to a sensible interval (say 5 seconds).
|
|
|
|
|
Dear Pete,
thanks to you I was able to make the program work. Thanks again for the patience you had with me ...
|
|
|
|
|
You're welcome, and I'm glad that we got there in the end.
|
|
|
|
|
Me too!
|
|
|
|
|
Pete, i'm sorry but i've another question for you: if i want authenticate the access on my ip address, what do i do?
the ipcamera in its home page has the authentication or as a simple user or as a administrator..
if i use HttpWebRequest i do the access with the credentials, but then i can't view the streaming, i think because the authentication executes every time.. have you a solution?
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Credentials = new NetworkCredential("user", "password");
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
|
|
|
|
|