Вы можете наилучшим образом добиться того, чего хотите в Silverlight, используя WebClient.OpenReadCompleted и OpenReadAsync. Это вернет поток. Вы можете использовать это напрямую или скопировать поток в байт [], как описано здесь, например: http://www.yoda.arachsys.com/csharp/readbinary.html
Кроме того, помните, что функциональность Silverlight для WebClient НЕ является подмножеством .NET. Если бы это было подмножество, то, что они оба делают, они делали бы то же самое. Но это не так. Например, OpenReadAsync в SL4 действительно является асинхронным. Он вообще не блокирует вызывающий поток. Однако в .NET4 OpenReadAsync и DownloadDataAsync частично блокируют вызывающий поток и хуже его блокируют при работе в отладчике. Чтобы получить действительно не блокирующий пользовательский интерфейс эффект в .NET4, вам нужно самостоятельно запустить загрузку в отдельном потоке. Кроме того, в Silverlight DownloadProgressUpdated запускается во время загрузки OpenReadAsync. В .NET это не так. Однако .NET DownloadDataAsync запускает DownloadProgressUpdated довольно похоже на OpenReadAsync в Silverlight.
Итак, если вы хотите добиться согласованности между проектом WPF и Silverlight, вы можете использовать OpenReadAsync непосредственно на стороне SL. На стороне WPF запустите DownloadDataAsync в отдельном потоке:
Thread downloadThread = new Thread(new ThreadStart(() => wc.DownloadDataAsync(uri)));
downloadThread.Start();
Затем в DownloadDataCompleted создайте MemoryStream из возвращенного байта [], если вы предпочитаете иметь его в виде потока. (Я не нашел дополнительных накладных расходов, которые могли бы существенно повлиять на производительность.)