为什么呼叫defer func() { recover() }()成功恢复恐慌goroutine,但呼叫defer recover()不?
作为一个简约的例子,这段代码并不恐慌
package main
func main() {
defer func() { recover() }()
panic("panic")
}
Run Code Online (Sandbox Code Playgroud)
但是,用恢复直接替换匿名函数恐慌
package main
func main() {
defer recover()
panic("panic")
}
Run Code Online (Sandbox Code Playgroud) 在这个问题中,我遇到了以下简化问题:
我们从一个带有value属性的Objects数组开始.我们想要为每个值计算它的总和的百分比,并将其作为属性添加到结构中.要做到这一点,我们需要知道值的总和,但这个总和不是事先计算的.
//Original data structure
[
{ "value" : 123456 },
{ "value" : 12146 }
]
//Becomes
[
{
"value" : 123456,
"perc" : 0.9104
},
{
"value" : 12146 ,
"perc" : 0.0896
}
]
Run Code Online (Sandbox Code Playgroud)
一个简单且可能最具可读性的解决方案是两次遍历数据结构.首先我们计算总和,然后计算百分比并将其添加到数据结构中.
var i;
var sum = 0;
for( i = 0; i < data.length; i++ ) {
sum += data[i].value;
}
for( i = 0; i < data.length; i++ ) {
data[i].perc = data[i].value / sum;
}
Run Code Online (Sandbox Code Playgroud)
我们是否可以只通过数据结构一次,并以某种方式告诉只有在知道整个总和后才能评估百分比表达式?
我主要对解决纯javascript问题的答案感兴趣.那就是:没有任何库.
运行此代码后:
var input = new List<T>( ... );
var result = input.Select( t => new U(t) );
U first1 = null;
foreach ( U u1 in result )
if ( first1 == null )
first1 = u1;
U first2 = null;
foreach ( U u2 in result )
if ( first2 == null )
first2 = u2;
Run Code Online (Sandbox Code Playgroud)
然后'first1 == first2'评估为false,即使两个U都包含相同的T.我还没有测试它,但我认为可以通过链接.ToList()或.ToArray()来评估为true进入Select()调用.
在比这个简单的插图复杂得多的实际代码中,用于决定是否应该附加.ToList()或.ToArray()的好经验法则是什么?我最初的想法是要么可以多次迭代的任何引用表达式,要么在潜在迭代不明显的情况下更安全,任何引用的表达式,其结果永远不会改变.
在PostgreSQL中,是在事务完成之前(之内)还是之后执行的DEFERRED触发器?
该文件说:
DEFERRABLE
NOT DEFERRABLE这可以控制是否可以延迟约束.在每个命令之后立即检查不可延迟的约束.检查可延迟的约束可以推迟 到事务结束(使用
SET CONSTRAINTS命令).
它没有指定它是否仍在事务内部或外部.我个人的经验说它在交易中,我需要它在外面!
是DEFERRED(或INITIALLY DEFERRED)触发器是在事务内部执行的吗?如果是,我怎么能将他们的执行推迟到交易完成的时间?
为了给你一个提示,我正在使用pg_notify和RabbitMQ(PostgreSQL LISTEN Exchange)发送消息.我在外部应用程序中处理此类消息.现在我有一个触发器,它通过在消息中包含记录的id来通知外部应用程序新插入的记录.但是,以一种非确定性的方式,偶尔,当我尝试通过其手头的id选择记录时,无法找到记录.那是因为事务尚未完成,并且记录实际上没有添加到表中.如果我只能在事务完成后推迟执行触发器,那么一切都会成功.
为了得到更好的答案,让我更接近现实世界来解释情况.实际情况比我之前解释的要复杂一些.该源代码可以在这里找到,如果任何人的兴趣.由于我不打算深入研究的原因,我必须从另一个数据库发送通知,以便实际发送通知,如:
PERFORM * FROM dblink('hq','SELECT pg_notify(''' || channel || ''', ''' || payload || ''')');
Run Code Online (Sandbox Code Playgroud)
我确信这使得整个情况变得更加复杂.
postgresql notifications triggers transactions deferred-execution
我怎样才能在C#中实现自己的延迟执行机制?
所以我举例说:
string x = DoFoo();
Run Code Online (Sandbox Code Playgroud)
是否有可能执行一些魔法,以便在我"使用"x之前DoFoo不会执行?
我一直在学习IQueryable和延迟加载/延迟执行查询.
是否可以通过WCF公开此功能?我想暴露LINQ到SQL服务,返回一个IQueryable,我可以然后在客户端执行额外的查询,最后使用.ToList的execute().OData格式在这种情况下是否适用?
如果可能的话,究竟是什么技术术语,什么是一些很好的教程,我可以遵循?谢谢.
linq wcf iqueryable custom-linq-providers deferred-execution
从我正在阅读的内容来看,现在广泛支持defer属性,但我从未看到它被使用或提及过.<script>
如果您不需要推迟内联脚本并且不动态添加脚本(这会导致IE9和Safari 4-中出现问题),那么您似乎可以可靠地使用它并且在指定顺序的DOMContentLoaded之前运行脚本(这不会发生async)
这基本上是大多数网站所需要的:在DOMready上按顺序运行几个或多个外部脚本.例如:
<script defer src='jquery.js'></script>
<script defer src='jquery.some-plugin.js'></script>
<script defer src='my-scripts.js'></script>
Run Code Online (Sandbox Code Playgroud)
为什么不广泛使用?我现在可以实际使用它吗?
我有一个接受Enumerable的函数.我需要确保对枚举数进行评估,但是如果它在List或其他"冻结"集合中已经准备就绪,我宁愿不创建它的副本(例如,通过ToList()或ToArray()).冻结我指的是已经建立了一组项目的集合,例如List,Array,FsharpSet,Collection等,而不是像Select()和where()这样的linq.
是否有可能创建一个函数"ForceEvaluation",可以确定枚举是否已将执行挂起,然后评估可枚举?
public void Process(IEnumerable<Foo> foos)
{
IEnumerable<Foo> evalutedFoos = ForceEvaluation(foos)
EnterLockedMode(); // all the deferred processing needs to have been done before this line.
foreach (Foo foo in foos)
{
Bar(foo);
}
}
public IEnumerable ForceEvaluation(IEnumerable<Foo> foos)
{
if(??????)
{ return foos}
else
{return foos.ToList()}
}
Run Code Online (Sandbox Code Playgroud)
}
经过一些研究后,我意识到这在任何实际意义上都是不可能的,并且需要对每个迭代器进行复杂的代码检查.
所以我将使用Mark的答案的变体并创建一个已知安全类型的白名单,并且只需调用ToList()不在白名单上的任何内容.
感谢大家的帮助.
编辑*经过更多的反思,我意识到这相当于停止问题.所以非常不可能.
在LINQ语句中创建新对象时,例如:
var list = new List<string>() { "a", "b", "c" };
var created = from i in list select new A();
Run Code Online (Sandbox Code Playgroud)
A级看起来像这样:
class A
{
public string Label;
}
Run Code Online (Sandbox Code Playgroud)
然后使用foreach循环修改A中的属性:
foreach (var c in created) {
c.Label = "Set";
}
Run Code Online (Sandbox Code Playgroud)
为什么在访问后面的对象时未设置值IEnumerable.例如,以下断言失败:
Assert.AreEqual("Set", created.ElementAt(2).Label);
Run Code Online (Sandbox Code Playgroud)
我想知道为什么会这样.我希望foreach语句执行查询,并触发对象的创建.MSDN文档声明:"查询的执行被推迟,直到在foreach或For Each循环中迭代查询变量".
我用.NET 4.5和Mono 3.2.0重现了这种行为.在访问创建的对象之前调用ToList它IEnumerable会使这个问题消失.
我遇到了一个奇怪的问题,我想知道我应该怎么做.
我有这个返回a的类,IEnumerable<MyClass>它是一个延迟执行.现在,有两个可能的消费者.其中一个对结果进行排序.
请参阅以下示例:
public class SomeClass
{
public IEnumerable<MyClass> GetMyStuff(Param givenParam)
{
double culmulativeSum = 0;
return myStuff.Where(...)
.OrderBy(...)
.TakeWhile( o =>
{
bool returnValue = culmulativeSum < givenParam.Maximum;
culmulativeSum += o.SomeNumericValue;
return returnValue;
};
}
}
Run Code Online (Sandbox Code Playgroud)
消费者只调用延迟执行一次,但是如果他们要调用它多,那么结果将是错误的,因为culmulativeSum不会重置.我通过单元测试无意中发现了这个问题.
解决问题的最简单方法.ToArray()是以一点点开销为代价添加和删除延迟执行.
我还可以在消费者类中添加单元测试,以确保它们只调用一次,但这不会阻止将来编码这个潜在问题的新消费者.
我想到的另一件事是进行后续执行.就像是
return myStuff.Where(...)
.OrderBy(...)
.TakeWhile(...)
.ThrowIfExecutedMoreThan(1);
Run Code Online (Sandbox Code Playgroud)
显然这不存在.实现这样的事情是一个好主意,你会怎么做?
否则,如果有一只我看不到的大粉红色大象,那么指出它将会受到赞赏.(我觉得有一个,因为这个问题是关于一个非常基本的场景:|)
这是一个糟糕的消费者使用示例:
public class ConsumerClass
{
public void WhatEverMethod()
{
SomeClass some = new SomeClass();
var stuffs = some.GetMyStuff(param);
var nb = stuffs.Count(); //first deferred execution …Run Code Online (Sandbox Code Playgroud) c# ×5
linq ×5
javascript ×2
.net ×1
.net-4.5 ×1
foreach ×1
go ×1
iqueryable ×1
lambda ×1
postgresql ×1
transactions ×1
triggers ×1
wcf ×1