【发布时间】:2017-01-22 05:15:12
【问题描述】:
我想每 3 秒从网络摄像机中抓取一张图像并将其放入图像控件(WPF 应用程序)中。
我正在使用此代码:
DispatcherTimer 定义
DispatcherTimer dispatcherTimer = new DispatcherTimer(TimeSpan.FromSeconds(3), DispatcherPriority.Background, DispatcherTimer_Tick, Application.Current.Dispatcher);
图片抓取代码
private void DispatcherTimer_Tick(object sender, EventArgs evA)
{
Dispatcher.Invoke(DispatcherPriority.Background,
new Action(() =>
{
try
{
BitmapFrame src;
var webRequest = (HttpWebRequest)WebRequest.Create(@"http://camera_ip/cgi-bin/video.cgi?msubmenu=jpg");
webRequest.Credentials = new NetworkCredential("user", "password");
webRequest.Proxy = null;
var response = (HttpWebResponse)webRequest.GetResponse();
var stream = response.GetResponseStream();
var streamReader = new StreamReader(stream);
src = BitmapFrame.Create(streamReader.BaseStream);
imageTelecamera.BeginInit();
imageTelecamera.Source = src;
imageTelecamera.EndInit();
}
catch (Exception ex)
{
DoLogD($"Error: {ex.Message}");
}
}
));
}
它工作正常,但是当我抓取图像时,UI 会冻结几毫秒。
为什么调度程序不能在不影响 UI 的情况下在后台工作?
【问题讨论】:
-
在 DispatcherTimer 的 Tick 处理程序中调用
Dispatcher.Invoke没有意义,因为在 UI 线程中已经调用了处理程序方法。除此之外,Invoke 不会在后台线程中调用任何东西。它做的相反:如果你从后台线程调用它,它会调用 UI 线程中的一个动作。 -
您可能希望在后台线程中调用抓取代码(例如,通过
System.Threading.Timer),并在调度程序操作中调用imageTelecamera.Source = src;。还不清楚BeginInit和EndInit应该在这里做什么,因为您似乎在 Image 控件上调用它们,这根本没有必要。
标签: wpf image user-interface httpwebrequest freeze