WebClient实例是否应在Silverlight中重用

时间:2010-12-14 22:16:00

标签: c# silverlight windows-phone-7

我正在为Windows Phone 7编写一个Silverlight应用程序,该应用程序有一个需要向WebClient.DownloadStringAsync发送多个请求的类()

我最好为每个请求创建一个新的WebClient实例,或者更有效地初始化字段中的单个实例并将其用于每个请求(确保一次只有一个请求处于活动状态) ?

public class MainViewModel : INotifyPropertyChanged
{
    private readonly WebClient _wc;

    public MainViewModel()
    {
        _wc = new WebClient
        {
            Credentials = new NetworkCredential( "yyyyyyy", @"xxxxxx" )
        };

    }

    readonly Uri _baseUrl = new Uri( @"https://some.web.url" );

    public void GetServices()
    {
        _wc.DownloadStringCompleted += GetServicesCompleted;
        var uri = new Uri( _baseUrl, "/path" );
        _wc.DownloadStringAsync( uri );
    }

    private void GetServicesCompleted( object sender, DownloadStringCompletedEventArgs e )
    {
        _wc.DownloadStringCompleted -= GetServicesCompleted;

        string result = e.Result;

        // other logic...

        GetServiceResources();
    }

    private void GetServiceResources()
    {
        _wc.DownloadStringCompleted += GetServicesResourcesDownloaded;
        var url = new Uri( _baseUrl, "/path2" );
        _wc.DownloadStringAsync( url );
    }

    // etc
}

2 个答案:

答案 0 :(得分:6)

如果你正在使用WebClient,我每次都会创建一个新的。我还会为DownloadStringCompleted事件使用lambda表达式,因为这样可以将所有相关逻辑保持在一起。
e.g:

var wc = new WebClient();
wc.DownloadStringCompleted += (sender, e) => { GetServiceResources(); };
wc.DownloadStringAsync(new Uri("http://example.com/path", UriKind.Absolute));

这应该使代码更易于阅读并因此维护。

因为你的smaple代码也有嵌套的web请求(已完成的事件会启动另一个请求),重用同一个客户端会使调试变得更加困难。

请注意WebClient会自动将已完成的事件编组回UI线程,因此您在此处执行的任何工作都将阻止该UI线程。如果您完成的事件除了对UI进行简单更新之外的任何其他操作,则建议使用HttpWebRequest来代替性能和可用性问题。

如果您可以并行运行它们,或者(甚至更好)将逻辑(和响应)合并到一个请求中,我还建议不要发出连续的Web请求。

答案 1 :(得分:2)

您还应该知道,如果有任何类似WCF客户端代理的话,如果连接期间出现问题,Web客户端可能不会保持快乐状态。也就是说,它可能不是容错的。

因此,我认为您应该每次都重新实例化它。另外,如果在using块中正确使用,您将更有效地管理资源(尽管BFree指出,WebClient并不是特别重的资源)。

这并不是特别有用,但对于WCF Web服务特定的解决方案,我们使用基于http://www.acorns.com.au/blog/?p=113的实现为我们的WCF Web服务代理提供容错Web客户端。我们需要这个,因为我们只是在启动时注入WCF端点(或在某些情况下模拟)的依赖项。