小编Rot*_*tem的帖子

为什么锁定对象必须是静态的?

使用私有静态只读对象来锁定多线程是很常见的.我知道私有通过收紧封装来减少锁定对象的入口点,因此可以访问最重要的内容.

但为什么静止?

private static readonly object Locker = new object();
Run Code Online (Sandbox Code Playgroud)

最后,该字段仅在我的班级中使用,我也可以使用它:

private readonly object Locker = new object();
Run Code Online (Sandbox Code Playgroud)

任何意见?

更新:

作为一个例子,我粘贴了这段代码(只是一个例子).我可以使用静态或非静态锁定器,两者都可以正常工作.考虑到下面的答案,我应该更喜欢这样定义我的储物柜?(对不起,我下周接受采访,需要知道每一个细节:)

private readonly object Locker = new object();
Run Code Online (Sandbox Code Playgroud)

以下是代码:

    private int _priceA;
    private int _priceB;
    private EventWaitHandle[] _waithandle;
    private readonly IService _service;

//ctor
public ModuleAViewModel(IService service)
    {
        _service = service;
        _modelA = new ModelA();
        _waithandle = new ManualResetEvent[2];
        _waithandle[0] = new ManualResetEvent(false);
        _waithandle[1] = new ManualResetEvent(false);
        LoadDataByThread();
    }


 private void LoadDataByThread()
        {
            new Thread(() =>
                           {
                               new Thread(() =>
                               { …
Run Code Online (Sandbox Code Playgroud)

c# multithreading locking

105
推荐指数
3
解决办法
7万
查看次数

Process.WaitForExit在不同的机器上不一致

此代码在大量计算机上按预期运行.但是在一台特定的机器上,呼叫WaitForExit()似乎被忽略了,实际上标志着该过程已经退出.

static void Main(string[] args)
{
    Process proc = Process.Start("notepad.exe");
    Console.WriteLine(proc.HasExited); //Always False
    proc.WaitForExit(); //Blocks on all but one machines
    Console.WriteLine(proc.HasExited); //**See comment below
    Console.ReadLine();
}
Run Code Online (Sandbox Code Playgroud)

请注意,与SO上的类似问题不同,被调用的过程是notepad.exe(出于测试原因),因此故障不太可能 - 即它不会产生第二个子过程并关闭.即便如此,也无法解释为什么它适用于所有其他机器.

在问题机器上,即使记事本仍然在屏幕和任务管理器中仍然清楚地打开第二次Console.WriteLine(proc.HasExited))返回调用true.

该机器运行的是Windows 7和.NET 4.0.

我的问题是; 该特定机器上的条件可能导致这种情况?我应该检查什么?

编辑 - 到目前为止我尝试过的事情/更新/可能相关的信息:

  • 重新安装.NET.
  • 关闭任务管理器中我不知道的任何进程.
  • Windows尚未在此计算机上激活.
  • 根据评论中的建议,我尝试使用"现有"进程ID,GetProcessesByName但这只是在问题机器上返回一个空数组.因此,很难说问题就是这样WaitForExit,因为GetProcessesByName即使在调用之前调用也没有返回进程WaitForExit.
  • 在问题机器上,生成的记事本进程的ParentID是代码手动启动的记事本进程的ID,换句话说,记事本正在生成子进程并终止自身.

.net c# process

15
推荐指数
1
解决办法
3334
查看次数

使用SIMD的查找表

我有一个很大的像素处理功能,我目前正在尝试使用内部函数进行优化.

作为一名SSE新手,我不知道如何处理涉及查找表的代码部分.

基本上,我试图矢量化以下vanilla C++代码:

 //outside loop
const float LUT_RATIO = 1000.0F;

//in loop
float v = ... //input value
v = myLookupTable[static_cast<int>(v * LUT_RATIO)];
Run Code Online (Sandbox Code Playgroud)

我在尝试什么:

//outside loop
const __m128 LUT_RATIO = _mm_set1_ps(1000.0F);

//in loop
__m128 v = _mm_set_ps(v1, v2, v3, v4); //input values
__m128i vI = _mm_cvtps_epi32(_mm_mul_ps(v, LUT_RATIO)); //multiply and convert to integers
v = ??? // how to get vI indices of myLookupTable?
Run Code Online (Sandbox Code Playgroud)

编辑:ildjarn提出了一个要求我澄清的观点.我不是试图为查找表代码实现加速,我只是试图避免必须将寄存器专门存储到浮点数中进行查找,因为这部分夹在理论上可以从SSE中获益的其他两个部分之间.

c++ sse simd

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

我是否应该打扰处理共享进程生命周期的对象?

我知道所有实现的对象IDisposable应该在不再需要时立即处理,以释放其非托管资源使用的内存.

我的问题涉及我知道的事实,直到主机进程本身终止为止.如果我处理它们会不会有任何区别?当进程死亡时,是否存在未释放内存的可能性?GDI对象怎么样?即使没有处理过程,GDI句柄是否会在进程死亡时被释放?

我完全明白,无论如何处理所有物体都是一种好习惯.我纯粹是出于好奇而问.

c# dispose idisposable

8
推荐指数
1
解决办法
269
查看次数

ConcurrentQueue导致内存泄漏

使用时我有内存泄漏ConcurrentQueue:

requestObject request = xxx;

Item obj= new Item ();
obj.MessageReceived += obj_MessageReceived;
obj.Exited += obj_Exited;

request.Key = obj.Key;

obj.AddRequest(request);

_queue.TryAdd(obj.Key, obj);
Run Code Online (Sandbox Code Playgroud)

在"已退出"回调中,我处置资源:

void LiveSphere_Exited(string key)
{
    Item instance;

    _queue.TryRemove(key, out instance);

    Task.Factory.StartNew(() =>
    {
        var wait = new SpinWait();
        while (instance.MessageCount > 0)
        {
            wait.SpinOnce();
        }
    })
    .ContinueWith((t) =>
    {
         if (instance != null)
         {
             //Cleanup resources
             instance.MessageReceived -= obj_MessageReceived;
             instance.Exited -= obj_Exited;
             instance.Dispose();
             instance = null;
         }
    });
}
Run Code Online (Sandbox Code Playgroud)

当我分析代码时,我仍然有一个根引用的"Item"对象,但我不知道我可以在哪里处理......,退出的方法被触发,_queue已从队列中删除了"Item"对象.

当我阅读文档时,concurrentqueue将引用复制到队列中.

你能帮我找出内存泄漏的位置吗?

c# memory-leaks

8
推荐指数
2
解决办法
5351
查看次数

Parallel.For使用step!= 1

有没有办法实现Parallel.For这个for循环的版本?

for (int i = 0; i < 100; i += 2) { DoStuff(i); }
Run Code Online (Sandbox Code Playgroud)

我没有看到接受步骤参数的重载,但我想不出任何理由这在逻辑上是不可能的.

对此问题的接受答案建议使用Parallel.ForEach一系列int使用生成的s Enumerable.Range,但在我的情况下,我使用线程本地数据,因此Parallel.ForEach不是一个选项.

另一个选择是检查i % 2 == 0我的循环体是否return,但是仍然执行线程本地数据初始化器Func和终结器Func.以下是演示此选项的代码段:

Parallel.For<Bar>(0, limit, 

    () => new Bar(), //thread local data initialize

    (i, state, local) => //loop body
    {
        if (i % 2 != 0) return local;
        local.foo += DoStuff(i);
        return local;
    },

    (local) => …
Run Code Online (Sandbox Code Playgroud)

c# parallel-processing for-loop task-parallel-library

8
推荐指数
2
解决办法
3447
查看次数

如何正确地逃避这个字符串

我有一个字符串,我发送到外部打印功能.
我需要用反斜杠填充字符串,以便正确打印.

具体来说,我需要一个接受此示例输入的方法:
This is a string\nwith a line break\ta tab\rand a carriage return.

并输出:
This is a string\\nwith a line break\\ta tab\\rand a carriage return.

我是否需要Replace对它的每个可能的逃脱角色进行暴力攻击?

尝试:
s.Replace("\\","\\\\") 不起作用,因为它正在寻找一个反斜杠文字.

s.Replace("\n","\\n") 显然有效,但我正在寻找的是一种通用的方法.

编辑: 请不要建议暴力方法,我明白实施这样的方法没问题.我的问题是,是否有更普遍的方法.

c# string

7
推荐指数
1
解决办法
696
查看次数

更改ComboBox的设计

我需要将Windows窗体的设计更改为ComboBox:
在此输入图像描述

我是否需要重新设计按钮并继承UserControl,并从零开始所有功能?

或者足以继承ComboBox,而我需要做的就是改变图形?
如果是这样,我该怎么做?

c# combobox winforms

7
推荐指数
1
解决办法
1165
查看次数

AutoResetEvent在Set之后立即重置

考虑以下模式:

private AutoResetEvent signal = new AutoResetEvent(false);

private void Work()
{
    while (true)
    {
        Thread.Sleep(5000);
        signal.Set();
        //has a waiting thread definitely been signaled by now?
        signal.Reset();
    }
}

public void WaitForNextEvent()
{
    signal.WaitOne();
}
Run Code Online (Sandbox Code Playgroud)

此模式的目的是允许外部消费者等待某个事件(例如 - 消息到达).WaitForNextEvent不是从课堂内调用的.

举一个应该熟悉的例子,考虑一下System.Diagnostics.Process.它公开了一个Exited事件,但它也公开了一个WaitForExit方法,它允许调用者同步等待,直到进程退出.这就是我想在这里实现的目标.

我需要的原因signal.Reset()是,如果一个线程调用WaitForNextEvent 之后 signal.Set()已经被调用(或者换句话说,如果.Set没有线程在等待时调用),它会立即返回,因为事件已经预先发出信号.

这个问题

  • 是否保证在调用之前WaitForNextEvent()将发出一个线程调用信号?如果没有,实施方法的其他解决方案是什么? signal.Reset()WaitFor

c# multithreading autoresetevent

7
推荐指数
1
解决办法
3191
查看次数

同步重绘窗口控件(使用阻塞方法)

我想要做的是导致一个控件(在同一个过程中,但我无法控制)重绘自己,并让我的代码阻塞,直到它完成重绘.

我尝试过使用,UpdateWindow但似乎并不等待重绘完成.

我需要等待它完成重绘的原因是我想在之后抓住屏幕.

该控件不是dotNet控件,它是常规的Windows控件.

我已经确认:

  • 手柄是正确的.
  • UpdateWindow 返回true.
  • 尝试InvalidateRect(hWnd, IntPtr.Zero, true)在呼叫之前发送UpdateWindow以确保窗口需要无效.
  • 尝试在控件的父窗口上执行相同的操作.

使用的代码:

[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool InvalidateRect(IntPtr hWnd, IntPtr rect, bool bErase);

[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool UpdateWindow(IntPtr hWnd);

public bool PaintWindow(IntPtr hWnd)
{
    InvalidateRect(hWnd, IntPtr.Zero, true);
    return UpdateWindow(hWnd);
}
//returns true
Run Code Online (Sandbox Code Playgroud)

c# winapi gdi redraw invalidation

6
推荐指数
1
解决办法
2924
查看次数