我有一个访问WCF Web服务的silverlight 2 beta 2应用程序.因此,它目前只能使用basicHttp绑定.Web服务将返回相当大量的XML数据.从带宽使用的角度来看,这看起来相当浪费,因为如果压缩,响应会小5倍(我实际上将响应粘贴到txt文件中并压缩它.).
请求确实有"Accept-Encoding:gzip,deflate" - 有没有办法让WCF服务gzip(或以其他方式压缩)响应?
我确实找到了这个链接,但它确实看起来有点复杂的功能应该是开箱即用的恕我直言.
好的 - 首先我使用System.IO.Compression作为答案标记了解决方案,因为我无法"看起来"让IIS7动态压缩工作.事实证明:
在IIS7动态压缩是一起工作的人.只是Nikhil的IE开发人员Helper插件没有显示它的工作原理.我的猜测是,由于SL将Web服务调用关闭到浏览器,浏览器"在幕后"处理它,而Nikhil的工具永远不会看到压缩响应.我能够通过使用Fiddler来确认这一点,Fiddler监视浏览器应用程序外部的流量.事实上,在提琴手中,响应是gzip压缩的!
System.IO.Compression解决方案的另一个问题是Silverlight CLR中不存在System.IO.Compression.
因此,从我的角度来看,在Silverlight中启用WCF压缩的EASIEST方法是在IIS7中启用动态压缩并且根本不编写任何代码.
如果是这样,您的政策是什么?您是否为所有源代码文件声明了版权/商业机密,或者您是否仅为那些包含商业秘密的商业秘密申请版权?
你能用法律术语发布样本评论块以及你是如何到达它的吗?
我提出这个问题,因为前一段时间,当我在IBM工作时,有一些具体的指示,说明在软件标题的合法部分放入什么似乎很有意义.索赔有不同程度的保护.最低的公开可用,在这种情况下,您将提供标准的"AS-IS"/"无保修"/"免费"/"保留此消息"条款.下一级声称Proprietrary/Confidential并声明只允许明确授权的个人访问(并且如果雇员/承包商结束他们的关系,他们必须返回/删除/去除等等.最高声称内容是商业秘密并且去了更深入.
我知道这不是一个严格的编程问题,但我想不出一个更好的地方来调查真正的开发人员做了什么,可能让人们发布他们的政策甚至样本标题(省略公司名称等)
我将首先发布我正在使用的那个作为答案.我通过在Google Code上运行搜索来构建它(奇怪而且具有讽刺意味的是,那里有很多这样的标题可供公开使用),然后从每个中获取最好的东西.
我希望SO社区可以向上/下投票并为每个答案添加评论,我们可以演变为其他人可以遵循的最佳实践.
如果这是最好的社区维基,我100%罚款.我会让别人做出决定.
在我开发一个漂亮的数据驱动的Silverlight应用程序的过程中,我似乎不断遇到某种需要解决的竞争条件.最新的一个在下面.任何帮助,将不胜感激.
后端有两个表:一个是组件,一个是制造商.每个组件都有一个制造商.根本不是一个不寻常的外键查找关系.
我是Silverlight,我通过WCF服务访问数据.我将调用Components_Get(id)来获取Current组件(查看或编辑)以及调用Manufacturers_GetAll()以获取制造商的完整列表,以填充ComboBox的可能选择.然后,我将ComboBox上的SelectedItem绑定到当前组件的制造商,将ComboBox上的ItemSource绑定到可能的制造商列表.像这样:
<UserControl.Resources>
<data:WebServiceDataManager x:Key="WebService" />
</UserControl.Resources>
<Grid DataContext={Binding Components.Current, mode=OneWay, Source={StaticResource WebService}}>
<ComboBox Grid.Row="2" Grid.Column="2" Style="{StaticResource ComboBoxStyle}" Margin="3"
ItemsSource="{Binding Manufacturers.All, Mode=OneWay, Source={StaticResource WebService}}"
SelectedItem="{Binding Manufacturer, Mode=TwoWay}" >
<ComboBox.ItemTemplate>
<DataTemplate>
<Grid>
<TextBlock Text="{Binding Name}" Style="{StaticResource DefaultTextStyle}"/>
</Grid>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</Grid>
Run Code Online (Sandbox Code Playgroud)
这是最好的工作时间,直到我变得聪明并做了一点客户端缓存组件(我计划为制造商打开).当我打开组件的缓存并获得缓存命中时,所有数据都将正确存在于对象中,但SelectedItem将无法绑定.原因是,在Silverlight中调用是异步的,并且在缓存的帮助下,在制造商之前不会返回Component.因此,当SelectedItem尝试在ItemsSource列表中找到Components.Current.Manufacturer时,它不存在,因为此列表仍然为空,因为尚未从WCF服务加载Manufacturers.All.同样,如果我关闭组件缓存,它会再次运行,但感觉不对 - 就像我很幸运时机正在运转.正确的修复恕我直言,MS用于修复ComboBox/ItemsControl控件,以了解这将发生Asynch调用是常态.但在那之前,我需要一种方法来解决它...
以下是我想到的一些选项:
任何想法/评论?
FWIW:我会在这里发布我的解决方案,以造福他人.
@Joe:非常感谢你的回复.我知道只需要从UI线程更新UI.这是我的理解,我想我已经通过调试器确认了这一点,在SL2中,服务参考生成的代码为您解决了这个问题.即当我调用Manufacturers_GetAll_Asynch()时,我通过Manufacturers_GetAll_Completed事件获得结果.如果查看生成的服务引用代码,它可确保从UI线程调用*Completed事件处理程序.我的问题不是这个,而是我做了两个不同的调用(一个用于制造商列表,一个用于引用制造商id的组件),然后将这两个结果绑定到一个ComboBox.它们都绑定在UI线程上,问题是如果列表在选择之前没有到达那里,
另请注意,如果您只是以错误的顺序设置ItemSource和SelectedItem,这仍然是一个问题!
另一个更新:虽然仍然存在组合框竞争条件,但我发现了一些有趣的东西.您永远不应该从该属性的"getter"中生成PropertyChanged事件.示例:在我的类型为ManufacturerData的SL数据对象中,我有一个名为"All"的属性.在Get {}中,它会检查它是否已被加载,如果没有,它会加载它:
public class ManufacturersData : DataServiceAccessbase
{
public ObservableCollection<Web.Manufacturer> All
{
get
{
if (!AllLoaded)
LoadAllManufacturersAsync();
return mAll;
}
private set
{
mAll …Run Code Online (Sandbox Code Playgroud) 有谁知道在Silverlight应用程序中检测用户不活动的有效方法.这个想法是,每当用户以任何方式与应用程序交互时,计时器都会重新加载.当它到期时,将显示"继续工作..."对话框一段时间,页面将重定向到/ Logout.
摩擦是检测不活动.思考?
如果我需要使用LINQ生成相当大的数据集,并且可能要花一些时间(例如几秒钟),并且我需要(希望)生成有关使用情况的反馈信息,是否有简单/首选的方法去做这个?
例如,假设我有1000辆汽车的列表A和1000辆卡车的列表B,并且我想选择所有可能的有序(汽车,卡车)对,其中car.color == truck.color链接如下:
var pairs = from car in A
from truck in B
where car.color==truck.color
select new {car, truck};
Run Code Online (Sandbox Code Playgroud)
现在,将在某些时候将其评估为一组嵌套的foreach循环。我希望能够报告完成的%%年龄,并且可以理想地更新进度条或其他内容。
编辑:查询后,我将结果存储在一个成员变量中,像这样的列表(这将强制执行查询):
mPairs = pairs.ToList();
Run Code Online (Sandbox Code Playgroud)
我这样做是因为我在后台工作线程中执行此操作,因为我不希望UI线程冻结,因为它会按需评估UI线程上的LINQ表达式(这在Silverlight BTW中)。因此,为什么我要报告进度。UX基本上是这样的:
(删除项目时必须执行类似的过程)
在构造LINQ表达式时(对我来说,linq到对象)有许多方法可以完成某些事情,有些方法比其他方法更好,更好,更有效.
编辑
感谢Richard/Jon的回答.
看起来我真正想要的是为LINQ表达式获取一个简单的Operation Count"OCount",虽然我不确定LINQ中是否存在钩子以允许它.假设我具有特定机器硬件(SLA)的目标性能级别.理想情况下,我会添加一个单元测试来确认通过该查询移动的典型数据将在指定的时间内(来自SLA)进行处理.问题是这将在构建服务器/开发人员机器/等上运行.这可能与SLA的机器硬件几乎没有相似之处.因此我的想法是,我将确定表达式的可接受的最大"OCount",知道如果OCount小于X,它肯定会在目标"典型"硬件上的SLA下提供可接受的性能.如果OCount超过此阈值,构建/单元测试会产生警告.理想情况下,我想有这样的东西(pseudocode-ish):
var results = [big linq expression run against test dataset];
Assert.IsLess(MAXALLOWABLE_OCOUNT, results.OCount)
Run Code Online (Sandbox Code Playgroud)
其中results.OCount只是给我生成结果集所需的总迭代次数(n).
我为什么喜欢这个?
好吧,即使是中等大小的LINQ表达式,由于增加了整体操作次数,一小部分更改/添加也会对性能产生巨大影响.应用程序代码仍将通过所有单元测试,因为它仍然会产生正确的结果,但在部署时工作速度很慢.
另一个原因是简单的学习.如果你做了什么并且OCount上升或下降了一个数量级,那么你就会学到一些东西.
编辑#2 我也会提出一个潜在的答案.它不是我的,它来自Cameron MacFarland来自另一个问题,我问这个产生了这个问题.事实证明,我认为这个问题的答案可以在单元测试环境中工作,就像我在第一次编辑这个问题时描述的那样.
它的本质是在单元测试夹具中创建测试数据集,您可以按照本答案中概述的方式将其输入LINQ表达式,然后将迭代计数相加并与最大允许迭代计数进行比较.
请参阅Cameron的答案
在vs2008中对silverlight用户控件的预览对我来说几乎没用,并且需要永远加载.我花了很多时间只切换到XAML并最小化我打开的每个Silverlight UserControl的预览.是否有一个设置,我可以告诉VS2008默认情况下打开这些只在XAML模式?
silverlight ×4
linq ×2
wcf ×2
comments ×1
compression ×1
data-binding ×1
gzip ×1
metrics ×1
optimization ×1