小编Lor*_*tté的帖子

C#async/await如何与更一般的结构相关,例如F#工作流或monad?

C#语言设计一直(历史上)一直致力于解决特定问题,而不是寻找解决潜在的一般问题:例如参见http://blogs.msdn.com/b/ericlippert/archive/2009/07/09/ "IEnumerable vs. coroutines"的iterator-blocks-part-one.aspx:

我们本来可以做得更普遍.我们的迭代器块可以看作是一种弱的协程.我们本可以选择实现完整的协同程序,并且只是使迭代器块成为协程的特例.当然,协同程序反过来不如一流的延续; 我们可以实现continuation,在continuation方面实现协程,并在协程方面实现迭代器.

或者http://blogs.msdn.com/b/wesdyer/archive/2008/01/11/the-marvels-of-monads.aspx for SelectMany作为(某种)Monads的代理人:

C#类型系统的功能不足以为monad创建通用抽象,这是创建扩展方法和"查询模式"的主要动力.

我不想问为什么会这样(已经给出了许多好的答案,特别是在Eric的博客中,这可能适用于所有这些设计决策:从性能到复杂性的增加,无论是编译器还是程序员).

我想要了解的是async/await关键字所涉及的"一般构造"(我最好的猜测是延续monad - 毕竟,F#async是使用工作流实现的,据我所知是一个延续monad),以及它们如何与它相关(它们如何不同?,缺少什么?,为什么存在差距,如果有的话?)

我正在寻找类似于我链接的Eric Lippert文章的答案,但与async/await相关而不是IEnumerable/yield.

编辑:除了很棒的答案,一些有用的链接到相关的问题和建议的博客文章,我正在编辑我的问题列出他们:

c# monads f# async-await

35
推荐指数
2
解决办法
2778
查看次数

在Mono中使用WebRequest的麻烦

我在ServiceStack Web应用程序中使用WebRequest有一个非常奇怪的问题(由Mono上的XSP托管).似乎请求模块的注册以一种非常奇怪的方式工作; 我正在使用WebRequest创建HTTP请求,但它失败了,因为它无法找到该"前缀"(HTTP)的创建者.

我看到的例外情况是NotSupportedException,我能够跟踪它没有为HTTP前缀注册创建者这一事实(我正在点击https://github.com/mono/mono/blob/master/mcs/class/ System/System.Net/WebRequest.cs,第479行)

编辑:更多细节:NotSupportedException抛出WebRequest.GetCreator,它使用URL前缀作为键来选择要返回的创建者; 在我的情况下,一个HttpRequestCreator.抛出异常是因为没有为"HTTP"前缀注册的创建者(实际上,根本没有创建者).

所以我搜索了一下,挖掘了Mono源代码,发现模块是(或应该)添加到system.web的webRequestModules部分的各种*.config文件中.

我查看了我的machine.config文件,它是: System.Net.HttpRequestCreator, System, Version=4.0.0.0

看看WebRequest Mono的来源 ,似乎前缀是从配置确实添加的,在类静态构造函数内(不是一个好的选择,恕我直言,但仍然......应该工作).

为了测试它,我尝试了添加HttpRequestCreatorsystem.net/webRequestModules我的web.config; 这是由XSP/Mono加载并导致重复的键异常(这是预期的,因为HttpRequestCreator应该已经加载,因为它已经存在于machine.config中).

更奇怪的是:如果我为Http添加一个模拟处理程序,就像这样:

bool res = System.Net.WebRequest.RegisterPrefix ("http", new MyHttpRequestCreator ());
Debug.Assert (res == false);
Run Code Online (Sandbox Code Playgroud)

断言有时会通过......有时候不会!(如果已经注册了相同前缀的创建者,则RegisterPrefix返回"false";我希望它总是返回false,但事实并非如此!再次,它是完全随机的)

当注册"失败"(即因为已经注册了"HTTP"前缀而返回false)时,WebRequest可以创建HTTP请求.就像调用RegisterPrefix"唤醒"静态构造函数并让它运行一样.

我很困惑:它似乎是执行WebRequest的静态构造函数时的竞争条件,但这没有意义(运行时保护带有锁的静态构造函数,IIRC)

我错过了什么?我该如何解决或解决这个问题?这是我的错(误解或遗漏某些东西)还是看起来像是一个Mono bug,因此我应该提交它吗?

细节:

mono --version Mono JIT编译器版本3.0.6(Debian 3.0.6 + dfsg-1~exp1~pre1)

(可能相关的,未回答的问题:单声道下WebRequest不支持HTTP协议)

mono httpwebrequest xsp servicestack

30
推荐指数
1
解决办法
1104
查看次数

CakePHP无法写入某些文件

我开始使用CakePHP为我的框架开发一个网站,我刚刚开始并且已经遇到过错误,我无法解决它们的含义.

Warning: _cake_core_ cache was unable to write 'cake_dev_en-us' to File cache in /Applications/XAMPP/xamppfiles/htdocs/evolvidsnew/lib/Cake/Cache/Cache.php on line 310
Warning: _cake_core_ cache was unable to write 'cake_dev_en-us' to File cache in /Applications/XAMPP/xamppfiles/htdocs/evolvidsnew/lib/Cake/Cache/Cache.php on line 310
Warning: /Applications/XAMPP/xamppfiles/htdocs/evolvidsnew/app/tmp/cache/persistent/ is not writable in /Applications/XAMPP/xamppfiles/htdocs/evolvidsnew/lib/Cake/Cache/Engine/FileEngine.php on line 320
Warning: /Applications/XAMPP/xamppfiles/htdocs/evolvidsnew/app/tmp/cache/models/ is not writable in /Applications/XAMPP/xamppfiles/htdocs/evolvidsnew/lib/Cake/Cache/Engine/FileEngine.php on line 320
Warning: /Applications/XAMPP/xamppfiles/htdocs/evolvidsnew/app/tmp/cache/ is not writable in /Applications/XAMPP/xamppfiles/htdocs/evolvidsnew/lib/Cake/Cache/Engine/FileEngine.php on line 320
Run Code Online (Sandbox Code Playgroud)

我也收到有关以下内容的错误:

Notice (1024): Please change the value of 'Security.salt' in app/Config/core.php to a salt value specific to …
Run Code Online (Sandbox Code Playgroud)

php cakephp cakephp-2.0

12
推荐指数
1
解决办法
3万
查看次数

最小核心转储(堆栈跟踪+仅当前帧)

我可以配置Linux上的核心转储吗?我想获得类似Windows迷你转储的东西(应用程序崩溃时有关堆栈帧的最小信息).我知道你可以设置核心文件的最大大小ulimit,但这不允许我控制核心内部的内容(即不能保证如果我将限制设置为64kb它会转储最后16页的例如,堆栈).

另外,如果可能的话,我想以编程方式(从代码中)设置它.我查看过所/proc/PID/coredump_filter提到的文件man core,但是对于我的目的来说似乎太粗糙了.

提供一些上下文:我需要微小的核心文件,原因有很多:我需要通过网络收集它们,用于众多(数千)客户端; 此外,这些是具有少量SD卡的嵌入式设备,以及用于网络连接的GPRS调制解调器.所以任何高于〜200k的东西都是不可能的.

编辑:我正在使用运行Linux 2.6.24的嵌入式设备.处理器是PowerPC.不幸的是,目前断路器支持powerpc-linux ,因此google breakpad不是一个选项

linux gcc gdb coredump

9
推荐指数
1
解决办法
6282
查看次数

将基于凭据的身份验证信息与OAuth链接

我正在实现一个概念验证站点,可以选择与外部提供商链接.外部提供程序将用于获取一些其他用户数据.提供者方便地使用OAuth 1.0a公开身份验证.

要获取数据,用户在提供程序站点上进行身份验证并授予权限.简单.

该站点使用ServiceStack.用户使用注册和登录CredentialsAuthProvider.我查看了ServiceStack上的文档,探讨了SocialBoostrapApi演示,并相应地建模了我的服务;

首先,我添加了一个User类,它将序列化到我的数据库,以保存其他数据.

然后,我创建了一个CustomUserSession来覆盖该OnAuthenticated方法.

Plugins.Add(new AuthFeature(() => new CustomUserSession(), new IAuthProvider[] {
            new CredentialsAuthProvider()
        }));
Run Code Online (Sandbox Code Playgroud)

我的OnAuthenticated方法与SocialBoostrapApi演示中的方法非常相似; 它遍历session.ProviderOAuthAccess并从中获取必要的信息(寻找"ExternalProvider"提供者的OAuthTokens).

当然,这意味着当用户在外部提供商处授予我的应用程序授权时,在OAuth回调中,我会获得accessstoken,secret,everything,并将其放入其中session.ProviderOAuthAccess.

当然,这适用于当前会话,但如果用户再次注销,则必须再次授权(获取新的访问令牌).

我需要一些方法将我在会话中输入的数据保存到数据库中; 我试着环顾四周但却一无所获(另见我的问题).

所以,我添加了代码将它们直接保存到DB:

var userOAuthProvider = oauthTokens.TranslateTo<UserOAuthProvider>();
userOAuthProvider.UserAuthId = user.Id;
this.TryResolve<IDbConnectionFactory>().Run(db => db.Save(userOAuthProvider)); 
Run Code Online (Sandbox Code Playgroud)

现在,当用户进行身份验证时,似乎ServiceStack获取此UserAuthId的所有令牌并将其置于会话中.好!

第一个问题

我是以正确的方式做的吗?

第二个问题

我可以摆脱User/ CustomUserSessionclasses,只需将我需要的其他信息存储在UserOAuthProvider/ 中的"Items"字典中OAuthTokens吗?这会让我的代码更简单..

第三个问题

最后OnAuthenticate,SocialBootstrapApi再次保存自定义用户表:

authService.TryResolve<IDbConnectionFactory>().Run(db => db.Save(user));
Run Code Online (Sandbox Code Playgroud)

为什么有必要?我想是从UserOAuthProviderUser表上的表中复制一些信息(例如,在新授权后的下次登录时),但为什么呢?该会话似乎已使用正确的数据初始化.

c# authentication oauth servicestack

8
推荐指数
0
解决办法
264
查看次数

任务TPL的Thread.Interrupt等价物

一些背景知识:我的C#代码调用了一些阻塞等待的非托管代码(C++).阻塞等待,但是,可报警(像Thread.Sleep-我想它调用WaitForSingleObjectExbAlertable TRUE下盖); 我肯定知道它是警觉的,因为它可以被"唤醒" QueueUserAPC.

如果我可以简单地使用托管线程,我只会调用阻塞方法,然后Thread.Interrupt在需要它时退出时使用"唤醒"线程; 这样的事情:

void ThreadFunc() {
    try {
           Message message;
           comObject.GetMessage(out message);
           //....
     }
     catch (ThreadInterruptedException) {
        // We need to exit
        return;
     }
}

var t - new Thread(ThreadFunc);
//....
t.Interrupt();
Run Code Online (Sandbox Code Playgroud)

(注意:我没有使用这个代码,但据我所知,它可能适用于这种特殊情况(在我的控制之外的非托管代码中可警告等待).我正在寻找的是最好的相当于(或更好的替代!)在TPL中的这个.

但是我必须使用TPL(任务而不是托管的线程),并且非托管方法不受我的控制(WaitForMultipleObjectEx例如,当我向事件发出信号时,我无法修改它以调用它并使其返回).

我正在寻找一个Thread.Interrupt等价的任务(将在底层线程上发布APC的东西).AFAIK,CancellationTokens要求代码是"任务感知",并且不要使用这种技术,但我不确定:发生了什么,我想知道,如果任务执行了Thread.Sleep(我知道有一个Task.Wait,但它只是为了拥有一个可以警告的非任务等待的例子,可以取消吗?

我的假设是错的(我的意思是,我可以只使用CT,一切都会起作用吗?但是如何?).

如果没有这样的方法......我愿意接受建议.我真的想避免混合线程和任务,或使用P/Invoke,但如果没有别的办法,我仍然希望以"最干净"的方式做到这一点(这意味着:没有粗鲁的中止,并且"Tasky":))

编辑:

对于那些好奇的人,我已经"确认"Thread.Interrupt可以在我的情况下工作,因为它调用QueueUserAPC.InterruptInternal然后Thread::UserInterrupt,它调用AlertAPC排队.它实际上非常聪明,因为它允许您休眠/等待然后唤醒线程而无需使用其他同步原语.

我只需要找到遵循相同流程的TPL原语

.net c# multithreading task-parallel-library

8
推荐指数
1
解决办法
642
查看次数

IL中的"最终"是什么意思?

使用ildasm/ilasm时,您可以观察编译器生成的MSIL/CIL代码(例如C#编译器),在某些情况下,您可以看到有标记为的方法virtual final.

final在这种情况下意味着什么?我的猜测是它意味着"此方法无法被覆盖",因此即使此方法在虚拟表中有一个插槽,该插槽也不能被派生类中的方法覆盖.

但是怎么样?它在实践中如何运作?

它只是由编译器强制执行(例如,如果您尝试覆盖密封方法,它将失败并出现编译错误)或CLR(例如,当您尝试重写方法时,CLR抛出),或两者都执行?有没有合法的方法"删除",绕过这个final,即编写一个覆盖此方法的派生类?

更新:我可能已经找到一种方法(见我自己的答案),但我不知道这一切是合法的,支持的,标准的,所以,我已经张贴在这个新的(但相关的)问题,另外一个问题在这里

我愿意接受评论,当然还有其他方式(如果它们存在!)来做.

c# clr overriding cil

8
推荐指数
2
解决办法
684
查看次数

Soundex算法的一些变化

该算法设置为在第一个单词上运行或直到它填充四个编码的字符串.例如,输入"Horrible Great"的结果是:H612.它忽略了第二个单词,换句话说,它只需要第二个单词的第一个字母来填充编码的字符串.

我想通过取第一个单词并找到它的编码字符串来改变它,然后取第二个单词并找到它的编码字符串; 输出应为"H614 G600".我想知道是否有办法通过改变**代码来做到这一点.
非常感谢 :)

    private string Soundex(string data)
    {
        StringBuilder result = new StringBuilder();
        if (data != null && data.Length > 0)
        {
            string previousCode = "", currentCode = "", currentLetter = "";
            result.Append(data.Substring(0, 1));
            for (int i = 1; i < data.Length; i++)
            {
                currentLetter = data.Substring(i,1).ToLower();
                currentCode = "";

                if ("bfpv".IndexOf(currentLetter) > -1)
                    currentCode = "1";
                else if ("cgjkqsxz".IndexOf(currentLetter) > -1)
                    currentCode = "2";
                else if ("dt".IndexOf(currentLetter) > -1)
                    currentCode = "3";
                else …
Run Code Online (Sandbox Code Playgroud)

c# java asp.net soundex

7
推荐指数
1
解决办法
3390
查看次数

MQ以异步方式处理,聚合和发布数据

一些背景,在得到真正的问题之前:

我正在开发一个由几个不同模块组成的后端应用程序.目前,每个模块都是一个命令行java应用程序,它是"按需"运行的(稍后会详细介绍).

每个模块都是一个"步骤",是一个更大的过程的一部分,您可以将其视为数据流; 第一步从外部源收集数据文件并将其推送/加载到某些SQL数据库表中; 然后根据不同的条件和事件(时间,数据库中存在数据,通过Web服务/ Web界面完成的消息和详细说明),从(1个或多个)DB表中获取数据,处理它们,并将它们写在不同的表格上.步骤在三个不同的服务器上运行,并从三个不同的DB读取数据,但只能在一个DB中写入.目的是汇总数据,计算指标和统计数据.

目前,每个模块都是定期执行的(从第一个模块的几分钟/小时,到链中最后一个模块的几天,需要聚合更多数据,因此等待"更长时间"从它们可用),使用的cronjob.运行一个模块(当前是一个java控制台应用程序),它会检查数据库中给定日期时间窗口中新的未处理信息,并完成其工作.

问题:它有效,但是......我需要扩展和维护它,这种方法开始显示其局限性.

  1. 我不喜欢依靠"民意调查"; 这是浪费,考虑到以前模块的信息足以在他们需要的信息可用时"告诉"链中的其他模块,并且他们可以继续.
  2. 它"缓慢":链条上的模块延迟了几天,因为我们必须确保数据是由前面的模块到达和处理的.所以我们"停止"这些模块,直到我们确定我们拥有所有数据.新增功能需要实时(不是很难,但"尽快")计算某些指标.一个很好的例子就是在这里发生的事情,在SO上,带有徽章!:)我需要获得一些非常相似的东西.

为了解决第二个问题,我将介绍"部分"或"增量"计算:只要我有一组相关信息,我就会处理它.然后,当一些其他链接信息到达时,我计算差异并相应地更新数据,但我还需要通知其他(从属)模块.

问题

- 1)哪种方法最好? - 2)相关:哪些是"通知"其他模块(在我的情况下是java可执行文件)相关数据可用的最佳方式?

我可以看到三种方式:

  • 将其他"非数据"表添加到数据库中,每个模块写入"嘿,我已经完成了这个并且它可用".当cronjob启动另一个模块时,它会读取表格,确定他可以计算子集xxx,然后执行.等等
  • 使用Message Queues,如ZeroMQ(或Apache Camel,如@mjn建议)而不是DB表
  • 使用像Redis这样的键值存储,而不是数据库表

编辑:我确信基于队列的方法是要走的路,我为完整性添加了"table + polling"选项,但现在我明白这只是一种分心(显然,每个人都会回答"是的,使用队列,民意调查是邪恶的" - 这是正确的!".因此,让我重新解释一下这个问题: 使用像Redis这样的pub/sub的键值存储使用MQ的优点/缺点是什么?

  • 3)有没有任何解决方案可以帮我完全摆脱cronjobs?

编辑:特别是,在可能的情况下,它意味着:在某些MQ和/或键值存储中是否有一种机制可以让我发布带有"时间"的消息?比如"在1天内交付"?显然,持久性和"几乎一次"交付保证

  • 4)我应该将此消息(基于事件?)的解决方案构建为集中式服务,并将其作为其中一个服务器上的守护程序/服务运行吗?
  • 5)我是否应该放弃按需启动订阅者的想法,让每个模块作为守护进程/服务连续运行?
  • 6)哪些是赞成和缺点(可靠性,单点故障与资源使用和复杂性......)?

编辑:这是我最关心的一点:我想"排队"自己根据队列中的消息激活"模块",类似于MSMQ激活.这是个好主意吗?Java世界中有什么东西可以实现它,我应该自己实现它(通过MQ还是通过Redis),还是应该将每个模块作为守护进程运行?(即使某些计算通常是在突发中发生,两小时处理然后是两天的空转?)

注意:我不能使用重型容器/ EJB(No Glassfish或类似产品)

编辑:骆驼对我来说似乎有点太重了.无论是在资源还是开发的复杂性方面,我都在寻找一些非常轻松的东西

java notifications dataflow message-queue redis

7
推荐指数
1
解决办法
753
查看次数

检查可遍历是否在Scala中具有多于1个元素的有效方法

我需要检查一下Traversable(我已经知道nonEmpty)是否有一个或多个元素.

我可以使用size,但(告诉我,如果我错了)我怀疑这可能是O(n),并遍历集合来计算它.

我可以查看是否tail.nonEmpty,或者是否.head != .last

这两种方法的优缺点是什么?有没有更好的办法?(例如,还会.last进行完整的迭代吗?)

scala scala-collections

6
推荐指数
1
解决办法
1431
查看次数