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.
编辑:除了很棒的答案,一些有用的链接到相关的问题和建议的博客文章,我正在编辑我的问题列出他们:
我在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的来源 ,似乎前缀是从配置确实添加的,在类静态构造函数内(不是一个好的选择,恕我直言,但仍然......应该工作).
为了测试它,我尝试了添加HttpRequestCreator
到system.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协议)
我开始使用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) 我可以配置Linux上的核心转储吗?我想获得类似Windows迷你转储的东西(应用程序崩溃时有关堆栈帧的最小信息).我知道你可以设置核心文件的最大大小ulimit
,但这不允许我控制核心内部的内容(即不能保证如果我将限制设置为64kb它会转储最后16页的例如,堆栈).
另外,如果可能的话,我想以编程方式(从代码中)设置它.我查看过所/proc/PID/coredump_filter
提到的文件man core
,但是对于我的目的来说似乎太粗糙了.
提供一些上下文:我需要微小的核心文件,原因有很多:我需要通过网络收集它们,用于众多(数千)客户端; 此外,这些是具有少量SD卡的嵌入式设备,以及用于网络连接的GPRS调制解调器.所以任何高于〜200k的东西都是不可能的.
编辑:我正在使用运行Linux 2.6.24的嵌入式设备.处理器是PowerPC.不幸的是,目前断路器不支持powerpc-linux ,因此google breakpad不是一个选项
我正在实现一个概念验证站点,可以选择与外部提供商链接.外部提供程序将用于获取一些其他用户数据.提供者方便地使用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
/ CustomUserSession
classes,只需将我需要的其他信息存储在UserOAuthProvider
/ 中的"Items"字典中OAuthTokens
吗?这会让我的代码更简单..
最后OnAuthenticate
,SocialBootstrapApi
再次保存自定义用户表:
authService.TryResolve<IDbConnectionFactory>().Run(db => db.Save(user));
Run Code Online (Sandbox Code Playgroud)
为什么有必要?我想是从UserOAuthProvider
User表上的表中复制一些信息(例如,在新授权后的下次登录时),但为什么呢?该会话似乎已使用正确的数据初始化.
一些背景知识:我的C#代码调用了一些阻塞等待的非托管代码(C++).阻塞等待,但是,可报警(像Thread.Sleep
-我想它调用WaitForSingleObjectEx
与bAlertable 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
,它调用Alert
APC排队.它实际上非常聪明,因为它允许您休眠/等待然后唤醒线程而无需使用其他同步原语.
我只需要找到遵循相同流程的TPL原语
使用ildasm/ilasm时,您可以观察编译器生成的MSIL/CIL代码(例如C#编译器),在某些情况下,您可以看到有标记为的方法virtual final
.
final
在这种情况下意味着什么?我的猜测是它意味着"此方法无法被覆盖",因此即使此方法在虚拟表中有一个插槽,该插槽也不能被派生类中的方法覆盖.
但是怎么样?它在实践中如何运作?
它只是由编译器强制执行(例如,如果您尝试覆盖密封方法,它将失败并出现编译错误)或CLR(例如,当您尝试重写方法时,CLR抛出),或两者都执行?有没有合法的方法"删除",绕过这个final
,即编写一个覆盖此方法的派生类?
更新:我可能已经找到一种方法(见我自己的答案),但我不知道这一切是合法的,支持的,标准的,所以,我已经张贴在这个新的(但相关的)问题,另外一个问题在这里
我愿意接受评论,当然还有其他方式(如果它们存在!)来做.
该算法设置为在第一个单词上运行或直到它填充四个编码的字符串.例如,输入"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) 一些背景,在得到真正的问题之前:
我正在开发一个由几个不同模块组成的后端应用程序.目前,每个模块都是一个命令行java应用程序,它是"按需"运行的(稍后会详细介绍).
每个模块都是一个"步骤",是一个更大的过程的一部分,您可以将其视为数据流; 第一步从外部源收集数据文件并将其推送/加载到某些SQL数据库表中; 然后根据不同的条件和事件(时间,数据库中存在数据,通过Web服务/ Web界面完成的消息和详细说明),从(1个或多个)DB表中获取数据,处理它们,并将它们写在不同的表格上.步骤在三个不同的服务器上运行,并从三个不同的DB读取数据,但只能在一个DB中写入.目的是汇总数据,计算指标和统计数据.
目前,每个模块都是定期执行的(从第一个模块的几分钟/小时,到链中最后一个模块的几天,需要聚合更多数据,因此等待"更长时间"从它们可用),使用的cronjob.运行一个模块(当前是一个java控制台应用程序),它会检查数据库中给定日期时间窗口中新的未处理信息,并完成其工作.
问题:它有效,但是......我需要扩展和维护它,这种方法开始显示其局限性.
为了解决第二个问题,我将介绍"部分"或"增量"计算:只要我有一组相关信息,我就会处理它.然后,当一些其他链接信息到达时,我计算差异并相应地更新数据,但我还需要通知其他(从属)模块.
- 1)哪种方法最好? - 2)相关:哪些是"通知"其他模块(在我的情况下是java可执行文件)相关数据可用的最佳方式?
我可以看到三种方式:
编辑:我确信基于队列的方法是要走的路,我为完整性添加了"table + polling"选项,但现在我明白这只是一种分心(显然,每个人都会回答"是的,使用队列,民意调查是邪恶的" - 这是正确的!".因此,让我重新解释一下这个问题: 使用像Redis这样的pub/sub的键值存储使用MQ的优点/缺点是什么?
编辑:特别是,在可能的情况下,它意味着:在某些MQ和/或键值存储中是否有一种机制可以让我发布带有"时间"的消息?比如"在1天内交付"?显然,持久性和"几乎一次"交付保证
编辑:这是我最关心的一点:我想"排队"自己根据队列中的消息激活"模块",类似于MSMQ激活.这是个好主意吗?Java世界中有什么东西可以实现它,我应该自己实现它(通过MQ还是通过Redis),还是应该将每个模块作为守护进程运行?(即使某些计算通常是在突发中发生,两小时处理然后是两天的空转?)
注意:我不能使用重型容器/ EJB(No Glassfish或类似产品)
编辑:骆驼对我来说似乎有点太重了.无论是在资源还是开发的复杂性方面,我都在寻找一些非常轻松的东西
我需要检查一下Traversable
(我已经知道nonEmpty
)是否有一个或多个元素.
我可以使用size
,但(告诉我,如果我错了)我怀疑这可能是O(n),并遍历集合来计算它.
我可以查看是否tail.nonEmpty
,或者是否.head != .last
这两种方法的优缺点是什么?有没有更好的办法?(例如,还会.last
进行完整的迭代吗?)