Каков наилучший способ постоянно менять изображение на WP7? - PullRequest
0 голосов
/ 25 февраля 2011

Я пытаюсь создать свой собственный тип удаленного рабочего стола для WP7. У меня есть служба WCF, которая возвращает изображение на экране целевой машины.

Вот код сервера WCF:

    // Method to load desktop image
Bitmap image = new Bitmap( ViewSize.Width, ViewSize.Height );
Graphics g = Graphics.FromImage( image );

g.CopyFromScreen( Position.X, Position.Y, 0, 0, ViewSize );

g.Dispose( );
return image;

// Convert image to byte[] which is returned to client
using ( MemoryStream ms = new MemoryStream( ) )
{
    Bitmap image = screenGrabber.LoadScreenImage( );
    image.Save( ms, ImageFormat.Jpeg );
    imageArray = ms.ToArray( );
}

Вот код для клиента WP7:

    MemoryStream stream = new MemoryStream( data );
BitmapImage image = new BitmapImage( );

image.SetSource( stream );
BackgroundImage.Source = image;

Переменная BackgroundImage является элементом управления Image.

Я заметил это зависание на эмуляторе через некоторое время, и в конечном итоге произойдет сбой из исключения OutOfMemoryException. Это уже довольно медленно (изображения появляются на полсекунды позже, чем на экране), и мне интересно, есть ли лучший / более быстрый способ сделать это? Любая помощь будет отличной. Заранее спасибо.

Ответы [ 2 ]

4 голосов
/ 25 февраля 2011

Я думаю, что могу пролить свет на ваше исключение OutOfMemoryException. Вам известен интерфейс IDisposable ? Тип MemoryStream является IDisposable, поэтому вы должны вызвать Dispose для него, чтобы убедиться, что он собирает мусор и все имеющиеся у него ресурсы освобождаются. Ваш код должен быть следующим:

using(MemoryStream stream = new MemoryStream( data ))
{
  BitmapImage image = new BitmapImage( );
  image.SetSource( stream );
}

Что касается производительности, приложения реального удаленного рабочего стола (RDP) не отправляют полное изображение экрана каждый раз, когда что-то меняется, они отправляют частичные обновления, чтобы минимизировать использование полосы пропускания.

Если вы собираетесь каждый раз выполнять полноэкранное обновление, убедитесь, что оно соответствующим образом масштабировано и сжато.

1 голос
/ 25 февраля 2011

ColinE прав, но есть нюанс. Если вы используете его код, он автоматически удалит изображение, как только оно будет установлено в качестве источника. Результатом этого будет либо ошибка, указывающая на то, что вы пытались обновить пользовательский интерфейс из потока, не являющегося пользовательским интерфейсом, либо возникновение проблемы при попытке визуализации уже расположенного растрового изображения.

Вместо этого я бы предпочел оставить ссылку на текущее изображение, затем изменить изображение, а затем использовать ссылку на предыдущее текущее изображение, чтобы удалить это изображение. У вас нет доступа к банкомату IDE, но что-то вроде этого (при условии, что код выполняется в потоке пользовательского интерфейса, в противном случае вам также нужно будет убедиться, что код вызывается там).

Поток MemoryStream = новый MemoryStream (данные); BitmapImage image = new BitmapImage ();
image.SetSource (stream);

IDisposable toDispose = (IDisposable) BackgroundImage.Source;

BackgroundImage.Source = image;

toDispose.Dispose ();

Также, если вы не хотите заново изобретать большую часть колеса, взгляните на VNC, VNC # - это библиотека для нее, и она дает вам разумное понимание того, как другие сделали удаленное взаимодействие на рабочем столе. перед тем

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...