当我运行以下测试(使用F#2.0构建)时,我得到OutOfMemoryException.在我的系统上达到异常需要大约5分钟(如果它作为x86进程运行,则为i7-920 6gb ram),但无论如何我们都可以看到内存在任务管理器中的增长情况.
module start_child_test
open System
open System.Diagnostics
open System.Threading
open System.Threading.Tasks
let cnt = ref 0
let sw = Stopwatch.StartNew()
Async.RunSynchronously(async{
while true do
let! x = Async.StartChild(async{
if (Interlocked.Increment(cnt) % 100000) = 0 then
if sw.ElapsedMilliseconds > 0L then
printfn "ops per sec = %d" (100000L*1000L / sw.ElapsedMilliseconds)
else
printfn "ops per sec = INF"
sw.Restart()
GC.Collect()
})
do! x
})
printfn "done...."
Run Code Online (Sandbox Code Playgroud)
我没有看到此代码有任何问题,也没有看到内存增长的任何原因.我做了替代实现以确保我的参数有效:
module start_child_fix
open System
open System.Collections
open System.Collections.Generic
open System.Threading
open System.Threading.Tasks
type …Run Code Online (Sandbox Code Playgroud) 这里有一些c#的测试程序:
using System;
struct Foo {
int x;
public Foo(int x) {
this.x = x;
}
public override string ToString() {
return x.ToString();
}
}
class Program {
static void PrintFoo(ref Foo foo) {
Console.WriteLine(foo);
}
static void Main(string[] args) {
Foo foo1 = new Foo(10);
Foo foo2 = new Foo(20);
Console.WriteLine(foo1);
PrintFoo(ref foo2);
}
}
Run Code Online (Sandbox Code Playgroud)
这里反汇编编译方法主要:
.method private hidebysig static void Main (string[] args) cil managed {
// Method begins at RVA 0x2078
// Code size 42 (0x2a)
.maxstack …Run Code Online (Sandbox Code Playgroud) 以下测试显示F#2.0中的Async.Sleep无法立即取消.只有在时间过后,我们才会收到"取消"通知.
module async_sleep_test
open System
open System.Threading
open System.Threading.Tasks
open System.Xml
let cts = new CancellationTokenSource()
Task.Factory.StartNew(fun () ->
try
Async.RunSynchronously(async{
printfn "going to sleep"
do! Async.Sleep(10000)
}, -1(*no timeout*), cts.Token)
printfn "sleep completed"
with
| :? OperationCanceledException ->
printfn "sleep aborted" // we will see it only after 10 sec.
| _ ->
printfn "sleep raised error"
) |> ignore
Thread.Sleep(100) // give time to the task to enter in sleep
cts.Cancel()
Thread.Sleep(100) // give chance to the task …Run Code Online (Sandbox Code Playgroud) 创建第一个用户后(在我的情况下,用户名为"root",密码为"root"),对于任何onvif请求,AXIS P3301(固件5.11.2)都会返回NotAuthorized soap fault:
<SOAP-ENV:Fault
SOAP-ENV:encodingStyle="http://www.w3.org/2003/05/soap-encoding"
xmlns:SOAP-ENV="http://www.w3.org/2003/05/soap-envelope">
<SOAP-ENV:Code>
<SOAP-ENV:Value>SOAP-ENV:Sender</SOAP-ENV:Value>
<SOAP-ENV:Subcode>
<SOAP-ENV:Value>ter:NotAuthorized</SOAP-ENV:Value>
</SOAP-ENV:Subcode>
</SOAP-ENV:Code>
<SOAP-ENV:Reason>
<SOAP-ENV:Text xml:lang="en">Sender not authorized</SOAP-ENV:Text>
</SOAP-ENV:Reason>
<SOAP-ENV:Detail>
The action requested requires authorization and the sender is not authorized
</SOAP-ENV:Detail>
</SOAP-ENV:Fault>
Run Code Online (Sandbox Code Playgroud)
根据ONVIF规范1.02,我使用用户名令牌配置文件 进行身份验证,详见http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0 .pdf.
下面是我用来形成soap请求的脚本:
xquery version "1.0";
declare copy-namespaces no-preserve, inherit;
<s:Envelope
xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
xmlns:s="http://www.w3.org/2003/05/soap-envelope">
<s:Header>
<o:Security
s:mustUnderstand="true"
xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<o:UsernameToken u:Id="UsernameToken-3ae8d972-d014-47b0-858b-2364f6119763">
<o:Username>{model/userName/text()}</o:Username>
<o:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">
{model/passwordDigest/text()}
</o:Password>
<o:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">
{model/nonce/text()}
</o:Nonce>
<u:Created>{model/created/text()}</u:Created>
</o:UsernameToken>
</o:Security>
</s:Header>
<s:Body>
<tds:GetDeviceInformation xmlns:tds="http://www.onvif.org/ver10/device/wsdl" />
</s:Body>
</s:Envelope>
Run Code Online (Sandbox Code Playgroud)
这是我发送请求的代码:
static …Run Code Online (Sandbox Code Playgroud) 我需要为包含具有类似 XPath 表达式的任何元素的序列的元素实现可序列化类型。它有非常简单的方案:
<xsd:complexType name="FilterType">
<xsd:sequence>
<xsd:any minOccurs="0" maxOccurs="unbounded" />
</xsd:sequence>
</xsd:complexType>
Run Code Online (Sandbox Code Playgroud)
该元素的语义在WSBaseNotification主题 4.2 中进行了描述。问题是要解释表达式,我们需要某种机制来解析其中使用的前缀(XmlReader 通过 LookupNamespace 提供此类功能)。但还有一个问题,现阶段无法解析表达式,我们甚至无法对表达式类型和方言做出任何假设。所以我们需要以某种方式收集该范围内所有定义的前缀。一些XmlReader-s(例如XmlTextReader)实现了IXmlNamespaceResolver通过 GetNamespacesInScope 提供此类功能的接口,但其中许多没有(例如XmlMtomReader)。这个类型在很多web服务请求中使用,web服务使用wcf框架并且有几个绑定,所以我们不能对XmlReader将使用什么做任何假设。这是这种类型的原型实现,如果我们有GetNamespacesInScope对于XmlReader:
[Serializable]
public class FilterType : IXmlSerializable {
public XElement[] Any;
public void ReadXml(XmlReader reader) {
var xelist = new LinkedList<XElement>();
reader.Read();
var dr = reader as XmlDictionaryReader;
var gns = reader.GetNamespacesInScope(); // need to implement
while (reader.NodeType != XmlNodeType.EndElement) {
if (reader.NodeType == XmlNodeType.Element) …Run Code Online (Sandbox Code Playgroud)