在这个问题中,Stephen Cleary接受的答案是LogicalCallContext无法正常使用异步.他还在这个 MSDN主题中发布了它.
LogicalCallContext保存一个Hashtable,存储发送到CallContext.LogicalGet/SetData的数据.它只是这个Hashtable的浅层副本.因此,如果您在其中存储可变对象,则不同的任务/线程将看到彼此的更改.这就是Stephen Cleary的示例NDC程序(在MSDN线程上发布)无法正常工作的原因.
但是AFAICS,如果你只在Hashtable中存储不可变数据(可能通过使用不可变集合),那应该有效,让我们实现一个NDC.
然而,Stephen Cleary也在接受的答案中说:
CallContext不能用于此.Microsoft特别建议不要使用CallContext进行远程处理以外的任何操作.更重要的是,逻辑CallContext不了解异步方法如何早期返回并稍后恢复.
不幸的是,该建议的链接已关闭(找不到页面).所以我的问题是,为什么不推荐这个?为什么我不能以这种方式使用LogicalCallContext?说它不理解异步方法是什么意思?从调用者的POV,他们只是返回任务的方法,不是吗?
ETA:另见其他问题.在那里,Stephen Cleary的答案说:
你可以使用CallContext.LogicalSetData和CallContext.LogicalGetData,但我建议你不要,因为当你使用简单的并行性时它们不支持任何类型的"克隆"
这似乎支持我的情况.所以我应该能够建立一个NDC,这实际上是我需要的,而不是log4net.
我写了一些示例代码,它似乎工作,但仅仅测试并不总是捕获并发错误.所以,由于其他帖子中有提示这可能不起作用,我仍然会问:这种方法有效吗?
ETA:当我从下面的答案中运行斯蒂芬提出的复制品时,我没有得到错误的答案,他说我会,我得到正确的答案.即使他说"这里的LogicalCallContext值总是"1"",我总是得到0的正确值.这可能是因为竞争条件?无论如何,我还没有在我自己的电脑上复制任何实际问题.这是我正在运行的确切代码; 它只在这里打印"真实",斯蒂芬说至少在某些时候应该打印"假".
private static string key2 = "key2";
private static int Storage2 {
get { return (int) CallContext.LogicalGetData(key2); }
set { CallContext.LogicalSetData(key2, value);}
}
private static async Task ParentAsync() {
//Storage = new Stored(0); // Set LogicalCallContext value to "0".
Storage2 = 0;
Task childTaskA = ChildAAsync();
// LogicalCallContext value here is always …Run Code Online (Sandbox Code Playgroud) 当我mtime使用Java 读取文件时Files.getLastModifiedTime,返回值被截断为整秒.我知道这可以在其他系统上使用毫秒分辨率的mtimes,那么我的不同之处呢?
这是一个完整的独立测试,可以编译和运行:
import java.nio.file.attribute.FileTime;
import java.nio.file.Files;
import java.nio.file.Paths;
public class Test {
public static void main(String[] args) throws java.io.IOException {
FileTime timestamp = Files.getLastModifiedTime(Paths.get("/tmp/test"));
System.out.println(timestamp.toMillis());
}
}
Run Code Online (Sandbox Code Playgroud)
输出是(使用我的特定测试文件)1405602038000,而ls显示:
$ ls --full-time /tmp/test
-rw-rw-r-- 1 daniel daniel 0 2014-07-17 16:00:38.413008992 +0300 /tmp/test
Run Code Online (Sandbox Code Playgroud)
我希望Java输出1405602038413.
我用ext4在Linux上运行.我尝试了openjdk 1.7和Oracle jdk 1.8.
对TLS的新Logjam攻击基于常见的DH组.此链接建议为每个服务器生成一个新的自定义2048位DH组.
如何在使用SSLEngine的Java服务器代码中设置自定义DH组?
ETA:如果我只使用短暂的DH密码套件,即使用DHE或ECDHE而不使用DH或ECDH的密码套件,我会安全吗?或者这是无关的?
我想实现ARM(自动资源管理)模式,其中资源是异步使用的.
假设我的资源看起来像:
class MyResource {
def foo() : Future[MyResource] = ???
// Other methods returning various futures
def close() : Unit = ???
}
object MyResource {
def open(name: String): Future[MyResource] = ???
}
Run Code Online (Sandbox Code Playgroud)
所需的使用模式是:
val r : Future[MyResource] = MyResource.open("name")
r flatMap (r => {
r.foo() /* map ... */ andThen {
case _ => r.close()
}
})
Run Code Online (Sandbox Code Playgroud)
省略的映射函数可能很复杂,涉及分支和链接期货,这些期货会重复调用r返回期货的方法.
我想确保r.close()在所有未来的延续完成(或失败)后调用.在每个呼叫站点手动执行此操作非常容易出错.这需要ARM解决方案.
scala-arm库通常是同步的.这段代码不会做正确的事情,因为在块内的期货完成之前会调用close():
for (r <- managed(MyResource.open("name"))) {
r map (_.foo()) // map …Run Code Online (Sandbox Code Playgroud) 如果Scala未来失败,并且没有"观察"失败的延续(或者唯一的延续使用map/flatMap并且在失败的情况下不运行),那么错误就不会被检测到.我希望至少记录这些错误,所以我可以找到错误.
我使用术语"观察到的错误",因为在.Net Tasks中,当GC收集Task对象时,有机会捕获"未观察到的任务异常".类似地,使用同步方法,可以记录终止线程的未捕获异常.
在Scala期货中,"观察"失败意味着某些延续或其他代码会在未来处置之前读取存储在未来值中的Exception.我知道最终确定不是确定性的或可靠的,并且可能这就是为什么它不能用于捕获未处理的错误,尽管.Net确实成功地做到了这一点.
有没有办法在Scala中实现这一目标?如果没有,我应该如何组织我的代码以防止未处理的错误错误?
今天我andThen checkResult附加了各种未来.但是很难知道何时使用它以及何时不使用:如果库方法返回Future,它不应该checkResult并记录错误本身,因为库用户可能会处理失败,因此责任落在用户身上.当我编辑代码时,我有时需要添加检查,有时需要删除它们,这种手动管理肯定是错误的.