我喜欢MVVM Light的Messenger及其灵活性,但是当我忘记明确取消注册收件人时(在Silverlight 4中),我遇到了内存泄漏.
原因在这里解释,但我很好,因为我认为明确取消注册收件人是一个好习惯,而不是依赖于Messenger使用弱引用.问题是说起来容易做起来难.
ViewModel很简单:您通常可以完全控制它们的生命周期,并且可以Cleanup()在不再需要它们时使用它们.
另一方面,视图更加棘手,因为它们是通过DataTemplates实例化和销毁的.对于前者 你可以把ItemsControlwith MyView和DataTemplate 想象成一个ObservableCollection<MyViewModel>.该MyView控件创建/绑定引擎收集的,你有没有什么好办法对他们手动调用清理().
我有一个解决方案,但想知道它是否是一个体面的模式或有更好的选择.我们的想法是从ViewModel发送一条特定的消息,告诉相关的View处理:
public class MyViewModel : ViewModelBase
{
...
public override void Cleanup()
{
// unregisters its own messages, so that we risk no leak
Messenger.Default.Unregister<...>(this);
// sends a message telling that this ViewModel is being cleaned
Messenger.Default.Send(new ViewModelDisposingMessage(this));
base.Cleanup();
}
}
public class MyView : UserControl, ICleanup
{
public MyView()
{
// registers to messages it actually …Run Code Online (Sandbox Code Playgroud) 这是F#中抽象成员的典型声明:
abstract member createEmployee : string -> string -> Employee
Run Code Online (Sandbox Code Playgroud)
您可以定义参数类型,但不能定义其名称.没有名称,在实现接口时如何判断每个参数是什么?换句话说,您如何知道接口是否希望实现为1-或2-?
1- member this.createEmployee firstName lastName = ...
2- member this.createEmployee lastName firstName = ...
Run Code Online (Sandbox Code Playgroud)
我是从错误的角度看待问题(习惯于C#)吗?
我有一个自托管的WCF服务(v4框架),它通过HttpTransport基于自定义的绑定公开.绑定使用的自定义MessageEncoder几乎BinaryMessageEncoder与添加gzip压缩功能有关.
Silverlight和Windows客户端使用Web服务.
问题:在某些情况下,服务必须返回非常大的对象,并且在响应多个并发请求时偶尔会抛出OutOfMemory异常(即使任务管理器报告该过程约为600 Mb).当消息即将被压缩时,自定义编码器中发生异常,但我认为这只是一种症状,而不是原因.例外情况是"未能分配x Mb",其中x为16,32或64,而不是一个过大的数量 - 因此我相信其他事情已经使这个过程接近某个限制.
服务端点定义如下:
var transport = new HttpTransportBindingElement(); // quotas omitted for simplicity
var binaryEncoder = new BinaryMessageEncodingBindingElement(); // Readerquotas omitted for simplicity
var customBinding = new CustomBinding(new GZipMessageEncodingBindingElement(binaryEncoder), transport);
Run Code Online (Sandbox Code Playgroud)
然后我做了一个实验:我改变TransferMode从Buffered到StreamedResponse (和相应的修改的客户端).这是新的服务定义:
var transport = new HttpTransportBindingElement()
{
TransferMode = TransferMode.StreamedResponse // <-- this is the only change
};
var binaryEncoder = new BinaryMessageEncodingBindingElement(); // Readerquotas omitted for simplicity
var customBinding = new …Run Code Online (Sandbox Code Playgroud) 我正在努力使用F#类型的签名表示法.例如,假设您有折叠功能:
let rec Fold combine acc l =
...
Run Code Online (Sandbox Code Playgroud)
可能有这种类型的签名:
('a -> 'b -> 'a) -> 'a -> list<'b> -> 'a
Run Code Online (Sandbox Code Playgroud)
我会读到的
一个有三个参数的函数:
并返回'a.
但是,对于我的穴居人大脑来说,将其表达为更有意义
('a, 'b -> 'a), 'a, list<'b> -> 'a
Run Code Online (Sandbox Code Playgroud)
我确定有一个语义原因,为什么参数用箭头与函数返回类型完全相同,但不知何故我错过了它,并且到目前为止在书籍/文章中没有找到明确的解释.每当我看到类型签名时,我都要花很多时间来理解它.我觉得我只是错过了让"解密"显而易见的那一小块难题.
有人可以赐教吗?
我注意到大多数异常消息都不包含特定于实例的详细信息,例如导致异常的值.它们通常只告诉您错误的"类别".
例如,尝试使用第3个序列化对象时.派对库,我收到了一条带有消息的MissingMethodException:
"没有为此对象定义无参数构造函数."
在许多情况下,这已经足够了,但通常(通常在开发期间)会发出类似的消息
"没有为'Foo'类型的对象定义无参数构造函数."
通过直接指导错误原因可以节省大量时间.
InvalidArgumentException是另一个示例:它通常告诉您参数的名称,但不是它的值.这似乎是大多数框架引发的异常,也适用于第三方库.
这是故意的吗?
暴露内部状态(如变量的"错误"值)是否存在安全隐含?
在编写不需要访问同一类的其他成员的私有方法时,如何在私有成员和let绑定之间进行选择?
我有一个坚实的.NET背景,除了ASP.NET MVC,我想接受.特别是我在WPF(MVVM),各种版本的Silverlight,LINQ(POCO和XML)以及核心框架(C#,VB和最近的F#)方面都有很多经验.
我缺少并且可能相关的是(显然除了ASP.NET MVC)LINQ to SQL和Entity Framework.
我知道"普通旧的"ASP .NET的基础知识(但实际上并没有超出基础知识),但我对SQL,HTML,CSS,JS等并不陌生.
问题:如果你从类似我的背景开始学习ASP.NET MVC3,你发现什么方法是有效的(或不是),因此会推荐?
注意:我应该提一下,我也对最佳实践和模式感兴趣.我自费发现这可能比学习"工作原理"更重要(例如,几乎每本WPF书都会教你关于模板,绑定等的所有内容,但不要提及MVVM或其他基本模式.一个大项目).
我正在尝试在F#中使用Dapper dot net来执行简单的SQLite查询.Dapper返回一组动态对象:在C#中使用它们很简单,但据我所知,F#没有开箱即用的动态属性查找实现.
这是有效的,但我想有更好的方法可以做到这一点,而不需要反思:
let (?) x prop =
let flags = BindingFlags.GetProperty ||| BindingFlags.InvokeMethod
x.GetType().InvokeMember(prop, flags, null, x, [||])
let doQuery () =
//...
let conn = new SQLiteConnection (connString)
conn.Open ()
conn.Query("select first_name from customers")
|> Seq.map (fun c -> c ? first_name)
|> List.ofSeq
Run Code Online (Sandbox Code Playgroud)
实施该方法的最佳方法是什么?在这种情况下运营商?
我在Silverlight 4中遇到一个跨域webservice调用遇到了一个奇怪的问题.
启动后,应用程序立即在同一主机上调用Web服务,但是在不同的端口上(例如,应用程序位于http://www.mydomain.com:80,Web服务位于http: //www.mydomain.com:81).没有涉及SSL.主机提供了一个正确的clientaccesspolicy.xml文件,大多数时候一切正常(如99.9%).
但是,在某些情况下,浏览器不会请求clientaccesspolicy.xml,因此Web服务调用被阻止,并因跨域错误而失败.
在典型情况下,这是您使用Fiddler或Chrome开发人员工具查看的一系列请求:
在某些情况下,你只能看到
如果满足以下所有条件,则仅在少数计算机上运行(均运行Windows 7):
在这些机器上,在这种情况下,问题是100%可重复的.
可能是什么导致了这个?我可以执行哪些步骤来跟踪问题?
我正在研究基本的2D CAD引擎,管道运算符显着改进了我的代码.基本上,几个函数以空间中的点(x,y)开始,并在多次移动操作后计算最终位置:
let finalPosition =
startingPosition
|> moveByLengthAndAngle x1 a1
|> moveByXandY x2 y2
|> moveByXandAngle x3 a3
|> moveByLengthAndAngle x4 a4
// etc...
Run Code Online (Sandbox Code Playgroud)
这非常容易阅读,我想保持这种方式.各种x1,a1等在实际代码中显然具有含义名称.
现在新的要求是引入异常处理.围绕整个操作链进行一次大尝试是不够的,因为我想知道哪一行引起了异常.我需要知道哪个参数无效,以便用户知道必须更改哪个参数.
例如,如果第一行(moveByLengthAndAngle x1 a1)引发异常,我想告诉类似"嘿,-90是a1的无效值!a1必须在45到90之间!".鉴于可以在序列中使用相同类型的许多操作,仅为每个操作定义不同的异常类型是不够的(在该示例中,我将无法判断错误是第一次还是最后一次移动).
显而易见的解决方案是在单个let语句中拆分链,每个语句在各自的try/with中.然而,这将使我漂亮和可读的代码有点凌乱,不再那么可读.
有没有办法满足这个要求,而不会牺牲当前代码的可读性和优雅性?
(注意.现在每个moveBy函数都会在出现错误的情况下引发异常,但我可以自由地更改ex.返回一个选项,一个更大的元组,或者只需要其他任何东西).
f# ×5
silverlight ×4
.net ×3
c# ×3
mvvm ×2
asp.net-mvc ×1
c#-to-f# ×1
dapper ×1
exception ×1
mvvm-light ×1
wcf ×1
wpf ×1