在C++中,实际上可以通过值抛出异常而无需在堆上分配内存,因此这种情况很有意义.但在.NET框架中OutOfMemoryException是一种引用类型,因此它是在堆上分配的.OutOfMemoryException当没有足够的内存来创建新对象时,.NET框架如何分配内存?
如您所知,Task.ConfigureAwait(false)在等待不需要捕获同步上下文的代码中的任务时调用是个好主意,否则会导致死锁.
那么,您需要多久捕获一次同步上下文?我的练习,很少.在大多数情况下,我正在使用"库"代码,这几乎迫使我一直使用Task.ConfigureAwait(false)它.
所以我的问题非常简单:为什么Task.ConfigureAwait(false)不是任务的默认选项?强制使用"高级"代码不是更好Task.ConfigureAwait(true)吗?这有历史原因,还是我错过了什么?
我在F#中创建了一个针对F#3.1运行时的项目(即FSharp.Core版本4.3.1).然后我创建了一个控制台C#应用程序,为我的F#项目添加了一个项目引用,添加了对FSharp.Core.dll 4.3.1的引用.
一切都编译没有任何错误或警告,但运行时抛出这个当我尝试使用F#项目中的任何类型时:
System.IO.FileLoadException : Could not load file or assembly 'FSharp.Core, Version=4.3.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference.
Run Code Online (Sandbox Code Playgroud)
当我的所有项目都引用4.3.1时,为什么它会搜索FSharp.Core 4.3.0?如果我将所有项目引用从4.3.1更改为4.3.0,那么一切都会正常工作,但是版本4.3.1是什么?
PS两个项目都针对.NET 4.5.1.我正在使用Microsoft Visual Studio 2013
假设我有以下类的层次结构:
struct Base
{
};
struct Derived : public Base
{
void DoStuffSpecificToDerivedClass()
{
}
};
Run Code Online (Sandbox Code Playgroud)
以下工厂方法:
std::unique_ptr<Base> factoryMethod()
{
auto derived = std::make_unique<Derived>();
derived->DoStuffSpecificToDerivedClass();
return derived; // does not compile
}
Run Code Online (Sandbox Code Playgroud)
问题是,return语句没有编译,因为std::unique_ptr没有具有协方差支持的复制构造函数(这是有道理的,因为它没有任何复制构造函数),它只有一个具有协方差支持的移动构造函数.
解决这个问题的最佳方法是什么?我可以想到两种方式:
return std::move(derived); // this compiles
return std::unique_ptr<Base>(derived.release()); // and this compiles too
Run Code Online (Sandbox Code Playgroud)
编辑1:我使用Visual C++ 2013作为我的编译器.return derived看起来像这样的原始错误消息:
Error 1 error C2664: 'std::unique_ptr<Base,std::default_delete<_Ty>>::unique_ptr(const std::unique_ptr<_Ty,std::default_delete<_Ty>> &)' : cannot convert argument 1 from 'std::unique_ptr<Derived,std::default_delete<Derived>>' to 'std::unique_ptr<Derived,std::default_delete<Derived>> &&'
Run Code Online (Sandbox Code Playgroud)
编辑2:它是标准VS 2013模板中新创建的控制台应用程序.我没有调整任何编译器设置.编译器命令行如下所示:
调试:
/Yu"stdafx.h" /GS …Run Code Online (Sandbox Code Playgroud) 请考虑以下代码:
private static void TestHashCode<T>()
{
dynamic initialValue = 10;
Console.WriteLine("{0}: {1}", typeof(T).Name, ((T)initialValue).GetHashCode());
}
TestHashCode<int>();
TestHashCode<uint>();
TestHashCode<long>();
TestHashCode<ulong>();
TestHashCode<short>();
TestHashCode<ushort>();
Run Code Online (Sandbox Code Playgroud)
输出:
Int32: 10
UInt32: 10
Int64: 10
UInt64: 10
Int16: 655370
UInt16: 10
Run Code Online (Sandbox Code Playgroud)
见之间的差异short和ushort?实际上,这些类的源代码是不同的:
// ushort
public override int GetHashCode()
{
return (int) this;
}
// short
public override int GetHashCode()
{
return (int) (ushort) this | (int) this << 16;
}
Run Code Online (Sandbox Code Playgroud)
但与此同时,GetHashCode()签名/未签名版本的实现int和long相同:
// int and uint
public override …Run Code Online (Sandbox Code Playgroud) 假设我有以下代码:
private static void Run()
{
TaskScheduler.UnobservedTaskException += delegate { Console.WriteLine("Unobserved task exception!"); };
try
{
RunAsync().Wait();
}
catch (Exception)
{
}
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
Thread.Sleep(Timeout.InfiniteTimeSpan);
}
private static async Task RunAsync()
{
var task1 = ThrowAsync();
var task2 = ThrowAsync();
await task1;
await task2;
}
private static async Task ThrowAsync()
{
throw new Exception("Test exception");
}
Run Code Online (Sandbox Code Playgroud)
此代码输出,Unobserved task exception!因为task2未观察到异常.
我的问题如下:有没有办法以编程方式确定哪个任务有未观察到的异常?例如,我想获取一个调用任务或类似的方法的堆栈跟踪:
Unobserved exception: task2 in RunAsync()
Run Code Online (Sandbox Code Playgroud)
遗憾的是,异常堆栈跟踪是不够的.上面的代码只是一个演示,在实际的应用程序中,我有时会有一些未观察到的任务异常,其堆栈跟踪如下:
System.AggregateException: A Task's exception(s) were not observed either by …Run Code Online (Sandbox Code Playgroud) 我真正喜欢JsonReaderJson.NET 的一点是,你总是知道当前位置的路径JsonReader。例如,我们有一个像这样的json:
{
"name" :
{
"first": "John",
"last": "Smith"
}
}
Run Code Online (Sandbox Code Playgroud)
如果我们站立或“John”元素,JsonReader.Path将是“name.first”
有没有办法实现类似的东西XmlReader?也许使用 XPath?例如,我们有一个这样的xml:
<root>
<name>
<first>John/<first>
<last>Smith</last>
</name>
</root>
Run Code Online (Sandbox Code Playgroud)
我想在站在“John”时获得“/root/name/first”,在站在“Smith”时获得“/root/name/last”
最近我检查了大量遗留的C++代码,发现了我以前从未见过的生产C++代码:
class Foo
{
public:
void Bar()
{
std::cout << "Hello from Bar()!" << std::endl;
}
void Bar() const
{
const_cast<Foo*>(this)->Bar();
}
};
Run Code Online (Sandbox Code Playgroud)
这是一个巨大的反模式吗?我的意思是,函数是const还是非const,提供两个版本的重点是什么?这是某种'const-correctness cheat',允许调用const函数是这样的情况:
void InvokeBar(const Foo& foo)
{
// oh boy! I really need to invoke a non-const function on a const reference!
foo.Bar();
}
Run Code Online (Sandbox Code Playgroud) 考虑以下代码:
private static async Task Main(string[] args)
{
await SetValueInAsyncMethod();
PrintValue();
await SetValueInNonAsyncMethod();
PrintValue();
}
private static readonly AsyncLocal<int> asyncLocal = new AsyncLocal<int>();
private static void PrintValue([CallerMemberName] string callingMemberName = "")
{
Console.WriteLine($"{callingMemberName}: {asyncLocal.Value}");
}
private static async Task SetValueInAsyncMethod()
{
asyncLocal.Value = 1;
PrintValue();
await Task.CompletedTask;
}
private static Task SetValueInNonAsyncMethod()
{
asyncLocal.Value = 2;
PrintValue();
return Task.CompletedTask;
}
Run Code Online (Sandbox Code Playgroud)
如果在.NET 4.7.2控制台应用程序中运行此代码,则将获得以下输出:
SetValueInAsyncMethod: 1
Main: 0
SetValueInNonAsyncMethod: 2
Main: 2
Run Code Online (Sandbox Code Playgroud)
我确实知道,输出的差异是由以下事实引起的:该事实实际上SetValueInAsyncMethod不是方法,而是由状态机执行的,AsyncTaskMethodBuilder该状态机在ExecutionContext内部捕获并且SetValueInNonAsyncMethod只是常规方法。
但是即使有了这种理解,我仍然有一些问题: …