使用私有静态只读对象来锁定多线程是很常见的.我知道私有通过收紧封装来减少锁定对象的入口点,因此可以访问最重要的内容.
但为什么静止?
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) 此代码在大量计算机上按预期运行.但是在一台特定的机器上,呼叫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.
我的问题是; 该特定机器上的条件可能导致这种情况?我应该检查什么?
编辑 - 到目前为止我尝试过的事情/更新/可能相关的信息:
GetProcessesByName但这只是在问题机器上返回一个空数组.因此,很难说问题就是这样WaitForExit,因为GetProcessesByName即使在调用之前调用也没有返回进程WaitForExit.我有一个很大的像素处理功能,我目前正在尝试使用内部函数进行优化.
作为一名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中获益的其他两个部分之间.
我知道所有实现的对象IDisposable应该在不再需要时立即处理,以释放其非托管资源使用的内存.
我的问题涉及我知道的事实,直到主机进程本身终止为止.如果我处理它们会不会有任何区别?当进程死亡时,是否存在未释放内存的可能性?GDI对象怎么样?即使没有处理过程,GDI句柄是否会在进程死亡时被释放?
我完全明白,无论如何处理所有物体都是一种好习惯.我纯粹是出于好奇而问.
使用时我有内存泄漏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将引用复制到队列中.
你能帮我找出内存泄漏的位置吗?
有没有办法实现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) 我有一个字符串,我发送到外部打印功能.
我需要用反斜杠填充字符串,以便正确打印.
具体来说,我需要一个接受此示例输入的方法:
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") 显然有效,但我正在寻找的是一种通用的方法.
编辑: 请不要建议暴力方法,我明白实施这样的方法没问题.我的问题是,是否有更普遍的方法.
我需要将Windows窗体的设计更改为ComboBox:

我是否需要重新设计按钮并继承UserControl,并从零开始所有功能?
或者足以继承ComboBox,而我需要做的就是改变图形?
如果是这样,我该怎么做?
考虑以下模式:
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我想要做的是导致一个控件(在同一个过程中,但我无法控制)重绘自己,并让我的代码阻塞,直到它完成重绘.
我尝试过使用,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)