webclient methods not available to my Silverlight application

江枫思渺然 提交于 2019-12-05 12:32:49

Silverlight has a stripped-down/compact version of the .NET Framework. See MSDN's documentation for the WebClient in Silverlight to see it has very few methods compared to its counterpart in the full .NET Framework.

Silverlight has only a subset of the functionality of the full .NET. More notably, it doesn't contain blocking methods for communication with web services. This makes the life of programmers a bit difficult, but it is a fantastic thing for users - you cannot (easily) write Silverlight applications that will hang when the server doesn't respond quickly.

If you can transfer the data as a text, you can use DownloadStringAsync method:

var wc = new WebClient();
wc.DownloadStringCompleted += (sender, e) => {
     string data = (string)e.Result;
     // Process the data here
   }
wc.DownloadStringAsync(new Uri(address));

If you need to transfer binary data, then you'll probably have to use HttpWebRequest class explicitly.

You can best achieve what you want in Silverlight by using WebClient.OpenReadCompleted and OpenReadAsync. This will return a stream. You can use that directly, or copy the stream into a byte[] as described here for example: http://www.yoda.arachsys.com/csharp/readbinary.html

Also, beware that Silverlight's functionality for WebClient is NOT a subset of .NET's. If it was a subset, then things that they both do, they'd do the same. But this is not the case. For example, SL4's OpenReadAsync really is asynchronous. It doesn't block the calling thread at all. In .NET4, however, OpenReadAsync and DownloadDataAsync do partially block the calling thread, and block it worse while running in the debugger. To get a truly non-UI-blocking effect in .NET4, you need to run the download in a separate thread yourself. Furthermore, in Silverlight, DownloadProgressUpdated fires nicely throughout the download for OpenReadAsync. In .NET it doesn't. However .NET's DownloadDataAsync does fire DownloadProgressUpdated in a fairly similar way to Silverlight's OpenReadAsync.

So, if you want to achieve consistency between a WPF and Silverlight project, you can use OpenReadAsync directly on the SL side. On the WPF side, fire off a DownloadDataAsync in a separate thread:

Thread downloadThread = new Thread(new ThreadStart(() => wc.DownloadDataAsync(uri)));
downloadThread.Start();

Then in DownloadDataCompleted, create a MemoryStream from the returned byte[], if you'd rather have it in stream form. (I haven't found the additional overhead to affect performance significantly.)

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!