小编Mat*_*son的帖子

在循环外添加一个Console.WriteLine()会改变循环的时间 - 为什么?

请考虑以下代码:

using System;
using System.Diagnostics;

namespace Demo
{
    class Program
    {
        static void Main(string[] args)
        {
            Stopwatch sw = new Stopwatch();

            for (int trial = 0; trial < 4; ++trial)
            {
                sw.Restart();
                loop1();
                Console.WriteLine("loop1() took " + sw.Elapsed);

                sw.Restart();
                loop2();
                Console.WriteLine("loop2() took " + sw.Elapsed);

                sw.Restart();
                loop3();
                Console.WriteLine("loop3() took " + sw.Elapsed);

                // Console.WriteLine(); // <-- Uncomment this and the timings change a LOT!
            }
        }

        static void loop1()
        {
            bool done = false;

            for (int i = 0; i …
Run Code Online (Sandbox Code Playgroud)

c#

14
推荐指数
1
解决办法
856
查看次数

为什么使用Func <>比在泛型序列创建器上使用new()约束要快得多

考虑以下代码......

在我对Windows 7 x64 PC(Intel i7 3GHz)上的RELEASE(不是调试!)x86版本的测试中,我获得了以下结果:

CreateSequence() with new() took 00:00:00.9158071
CreateSequence() with creator() took 00:00:00.1383482

CreateSequence() with new() took 00:00:00.9198317
CreateSequence() with creator() took 00:00:00.1372920

CreateSequence() with new() took 00:00:00.9340462
CreateSequence() with creator() took 00:00:00.1447375

CreateSequence() with new() took 00:00:00.9344077
CreateSequence() with creator() took 00:00:00.1365162
Run Code Online (Sandbox Code Playgroud)

似乎使用Func <>来定义委托以创建新对象比直接调用"new T()"快6倍.

我觉得这有点出乎意料......我想这是因为Jitter完成了一些内联,但我认为它本来可以优化"新T()".

有没有人对此有解释?

也许我犯了一些错误.(我已经考虑了垃圾收集器可能产生的影响,但重新排列代码并添加GC.Collect()等不会显着改变结果).

无论如何,这是代码:

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;

namespace ConsoleApplication6
{
    class Program
    {
        static void Main(string[] args)
        {
            Stopwatch sw = new Stopwatch();

            int repeats …
Run Code Online (Sandbox Code Playgroud)

c# optimization

13
推荐指数
1
解决办法
190
查看次数

ManualResetEventSlim:调用.Set()后紧跟.Reset()不释放*any*等待线程

ManualResetEventSlim:立即调用.Set()后跟.Reset()不会释放任何等待的线程

(注意:这也适用于ManualResetEvent,而不仅仅是ManualResetEventSlim.)

我在发布和调试模式下都尝试了下面的代码.我在四核处理器上运行的Windows 7 64位上使用.Net 4运行32位版本.我是从Visual Studio 2012编译的(所以安装了.Net 4.5).

我在系统上运行时的输出是:

Waiting for 20 threads to start
Thread 1 started.
Thread 2 started.
Thread 3 started.
Thread 4 started.
Thread 0 started.
Thread 7 started.
Thread 6 started.
Thread 5 started.
Thread 8 started.
Thread 9 started.
Thread 10 started.
Thread 11 started.
Thread 12 started.
Thread 13 started.
Thread 14 started.
Thread 15 started.
Thread 16 started.
Thread 17 started.
Thread 18 started.
Thread …
Run Code Online (Sandbox Code Playgroud)

c# multithreading

13
推荐指数
1
解决办法
3847
查看次数

Debug.WriteLine()与Console.WriteLine()以不同方式处理文化.为什么?

请考虑以下Console App代码:

Thread.CurrentThread.CurrentCulture = new CultureInfo("en-GB");
Thread.CurrentThread.CurrentUICulture = Thread.CurrentThread.CurrentCulture;

DateTime date = new DateTime(2014, 01, 19);

Console.WriteLine("{0}", date); // Prints 19/01/2014
Debug.WriteLine("{0}", date);   // Prints 01/19/2014
Debug.WriteLine(date);          // Prints 19/01/2014
Run Code Online (Sandbox Code Playgroud)

如评论中所述,Console.WriteLine()打印19/01/2014Debug.WriteLine()打印01/19/2014.

更糟糕的是 - Debug.WriteLine("{0}", date)给出不同的输出Debug.WriteLine(date)......

是否会Debug.WriteLine()忽略线程的文化设置?

有没有办法Debug.WriteLine()利用线程的文化设置?或者我必须使用String.Format()并将结果传递给Debug.WriteLine()

(注意:我在Windows 8.1 64位,en-GB上使用Visual Studio 2013和.Net 4.51以及AnyCPU调试版本运行.)

.net c# culture date-formatting

13
推荐指数
2
解决办法
1613
查看次数

如何使用string.Format()格式化大括号括起来的十六进制数?

输入: uint hex = 0xdeadbeef;

所需输出: string result = "{deadbeef}"

第一种方法:明确添加{}; 这工作:

result = "{" + string.Format("{0:x}", hex) + "}"; // -> "{deadbeef}"
Run Code Online (Sandbox Code Playgroud)

使用转义大括号输出为十进制而不是十六进制:

result = string.Format("{{{0}}}", hex); // -> "{3735928559}"
Run Code Online (Sandbox Code Playgroud)

似乎很有希望,现在我们需要做的就是:x按照上面的第一种方法添加十六进制说明符:

result = string.Format("{{{0:x}}}", hex); // -> "{x}"
Run Code Online (Sandbox Code Playgroud)

哦,亲爱的,添加它':x已经使它输出"{x}"而不是"{deadbeef}"我想要的.

所以我的问题是:我必须通过显式添加{}按照第一个示例来解决这个问题,或者有没有办法使用复合格式化并转义大括号?

另请注意,这也会影响字符串插值(毕竟)只是由编译器转换为调用string.Format().

(这可能是重复的问题,但到目前为止我一直无法找到重复...)

编辑

c# string.format

13
推荐指数
1
解决办法
1836
查看次数

CA2104警告:有没有办法将类标记为"不可变"来抑制它?

请考虑以下代码,这些代码会引发 CA2104: Do not declare read only mutable reference types.

public class Test
{
    // This provokes CA2104: "Do not declare read only mutable reference types".
    protected readonly ImmutableClass ImmutableMember;
}

public class ImmutableClass
{
}
Run Code Online (Sandbox Code Playgroud)

有没有人知道一种方法将一个类标记为不可变的方式会抑制警告CA2104?

我试着装饰MutableClass[ImmutableObject(true)]没有成功的希望(因为表格编辑器使用的属性非常清楚),而且确实它不起作用.

我假设Code Analysis在确定是否发出CA2104时使用已知的不可变类型列表,因此我们不能使用相同的方法.

我想即使你可以将一个类标记为不可变,编译器也无法实际检查它是否为真,但至少它可能是一个有用的指标.

无论如何,我有什么属性可以忽略吗?如果没有,则必须进行抑制.

目前似乎没有替代方法可以做到这一点.

我找到了一个有趣的博客,来自Joe Duffy("Windows上的并发编程"一书的作者)关于这种事情.

他从"想象我们有一个ImmutableAttribute"开始....... :)

这很有意思 - 他遇到了编写一些新的FxCop规则来分析属于不可变的类型的麻烦.

c# code-analysis immutability

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

List.Contains()的循环实现看起来比内置的快.是吗?如果是这样,为什么?

(这个问题来自于此处开始的讨论)

我是比较时机与寻找true一个值List<bool>使用List.Contains()与那些手卷循环.

我看到其他人报道的结果不同.我已经在几个系统上尝试过它,在我尝试过的所有系统上,循环看起来要快2到3.5倍.这些系统的范围从运行XP.4的笔记本电脑到运行Windows 8和.Net 4.5的最新PC.

其他人报告的结果不同,即List.Contains()与循环速度大致相同或略快于循环.

这是我的测试代码.

using System;
using System.Collections.Generic;
using System.Diagnostics;

namespace ConsoleApplication1
{
    internal class Program
    {
        private static void Main()
        {
            int size = 10000000;
            int count = 10;
            List<bool> data = new List<bool>(size);

            for (int i = 0; i < size; ++i)
                data.Add(false);

            var sw = new Stopwatch();

            for (int trial = 0; trial < 5; ++trial)
            {
                sw.Restart();

                for (int i = 0; i …
Run Code Online (Sandbox Code Playgroud)

c# optimization generic-list

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

在数组中,只读结构应该是不可变的吗?

(注意:此示例代码需要C#7.2或更高版本以及Nuget System.Memory包.)

我们假设我们有readonly struct如下:

public readonly struct Test
{
    public Test(int value)
    {
        Value = value;
    }

    public int Value { get; }
}
Run Code Online (Sandbox Code Playgroud)

现在让我们把它放到一个数组中:

var array = new Test[] { new Test(1) };

Console.WriteLine(array[0].Value); // Prints 1
Run Code Online (Sandbox Code Playgroud)

到现在为止还挺好.您无法编写代码来array[0].Value直接修改.

现在假设我们这样做:

array.AsSpan().AsBytes()[3] = 1;

Console.WriteLine(array[0].Value); // Prints 16777217
Run Code Online (Sandbox Code Playgroud)

所以现在我们已经修改Value了数组中readonly结构的组件.

这种行为是否正确?

c# immutability c#-7.2 system.memory

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

如何将 CallerArgumentExpression 与 Visual Studio 2022 和 .net Standard 2.0 或 .net 4.8 一起使用?

在 Visual Studio 2022 和 .net 6.0 中,我们有了新CallerArgumentExpression属性,可以用来“捕获传递给方法的表达式,以便在诊断/测试 API 中提供更好的错误消息并减少击键次数”

例如,我们可以编写一个类来检查方法参数是否为空,如下所示:

public static class Contract
{
    public static T RequiresArgNotNull<T>(T? item, [CallerArgumentExpression("item")] string? expression = default, string? message = null)
        where T : class
    {
        if (item == null)
            throw new ArgumentNullException(
                expression ?? "<unknown>",
                message ?? (expression != null ? "Requires " + expression + " != null" : "RequiresArgNotNull() failed."));

        return item;
    }
}
Run Code Online (Sandbox Code Playgroud)

可以像这样使用:

using static ClassLibrary1.Contract; // To allow just putting …
Run Code Online (Sandbox Code Playgroud)

c# visual-studio-2022

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

Console.ReadKey()与多线程的奇怪行为

Console.ReadKey()在多线程程序中使用时,我遇到了一个奇怪的问题.

我的问题是:为什么会这样?这是一个错误,还是因为我在滥用Console?(请注意,根据文档,控制台应该是线程安全.)

用代码解释这个是最容易的:

using System;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApplication2
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            Console.WriteLine("X");  // Also try with this line commented out.
            Task.Factory.StartNew(test);
            Console.ReadKey();
        }

        private static void test()
        {
            Console.WriteLine("Entering the test() function.");
            Thread.Sleep(1000);
            Console.WriteLine("Exiting the test() function.");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

如果你运行它并且没有按键,你认为会打印出什么?

答案正是您所期望的:

X
Entering the test() function.
Exiting the test() function.
Run Code Online (Sandbox Code Playgroud)

现在注释掉Console.WriteLine("X")并再次运行它(不按键).我希望看到这个输出:

Entering the test() function. …
Run Code Online (Sandbox Code Playgroud)

c# multithreading console-application

9
推荐指数
2
解决办法
3931
查看次数