Articles of multithreading

为什么局部变量不能在C#中出现波动?

public void MyTest() { bool eventFinished = false; myEventRaiser.OnEvent += delegate { doStuff(); eventFinished = true; }; myEventRaiser.RaiseEventInSeperateThread() while(!eventFinished) Thread.Sleep(1); Assert.That(stuff); } 为什么eventFinished不能变得不稳定并且重要吗? 在我看来,在这种情况下,编译器或运行时可能会变得聪明,并且在while循环中“知道”eventFinished只能为false。 特别是当您考虑提升变量作为类的成员生成的方式以及委托作为同一类的方法时,从而剥夺了eventFinished曾经是局部变量这一事实的优化。

如何在C#中等待单个事件,超时和取消

所以我的要求是让我的函数等待第一个实例,来自另一个类和另一个线程的event Action ,并在我的线程上处理它,允许等待被超时或CancellationToken中断。 我想创建一个我可以重用的generics函数。 我设法创造了一些(我认为)我需要的选项,但两者看起来都比我想象的要复杂得多。 用法 为了清楚serialDevice ,此函数的示例使用将如下所示,其中serialDevice在单独的线程上吐出事件: var eventOccurred = Helper.WaitForSingleEvent( cancellationToken, statusPacket => OnStatusPacketReceived(statusPacket), a => serialDevice.StatusPacketReceived += a, a => serialDevice.StatusPacketReceived -= a, 5000, () => serialDevice.RequestStatusPacket()); 选项1-ManualResetEventSlim 这个选项并不错,但是对于ManualResetEventSlim的Dispose处理比看起来应该更糟糕。 它给了ReSharper适合我在闭包内访问修改/处理的东西,而且真的很难遵循,所以我甚至不确定它是否正确。 也许有一些我遗漏的东西可以清理它,这是我的偏好,但我不会随便看到它。 这是代码。 public static bool WaitForSingleEvent(this CancellationToken token, Action handler, Action<Action> subscribe, Action<Action> unsubscribe, int msTimeout, Action initializer = null) { var […]

C#AsyncCallback是否创建了一个新线程?

我编写了一个侦听其中一个端口的HttpListener : httpListener.BeginGetContext(new AsyncCallback(ListenerCallback), httpListener); ListenerCallback处理在侦听器uri上接收的任何请求。 如果在处理请求期间发生exception,它将运行一个诊断例程,该例程尝试命中侦听器uri以检查侦听器是否实际处于活动状态并侦听uri并写入侦听器返回的响应日志。 Listener只是将字符串Listening…返回给这样的虚拟请求。 现在在测试期间,当导致执行诊断模块的其他模块发生exception时,我可以看到监听器在检查日志时正确地返回了Listening… 但是,当ListenerCallback发生exception时,尝试命中诊断内的侦听器URI会引发以下exception: System.Net.WebException : The operation has timed out at System.Net.HttpWebRequest.GetResponse() at MyPackage.Diagnostics.hitListenerUrl(String url) in c:\SW\MyApp\MyProj\Diagnostics.cs:line 190 诊断模块中的第190行如下: 189 HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); 190 HttpWebResponse response = (HttpWebResponse)request.GetResponse(); 现在,如果AsyncCallback调度新线程并在该新线程中运行ListenerCallback ,则在通过诊断发送虚拟请求时,它不得导致Operation Timeout 。 这就是我认为理想的行为,因为它是*Async*Callback 。 事实上MSDN也说同样的话 : 使用AsyncCallback委托在单独的线程中处理异步操作的结果。 但似乎并非如此。 我在这里错过了什么吗? 视觉解读:

拨打许多网络服务的最佳方式?

我有30家子公司,每家公司都实施了他们的网络服务(使用不同的技术)。 我需要实现一个Web服务来聚合它们,例如,所有子公司Web服务都有一个名为GetUserPoint(int nationalCode)的Web方法,我需要实现我的Web服务,它将调用所有这些并收集所有的回复(例如积分总和)。 这是我的基类: public abstract class BaseClass { // all same attributes and methods public long GetPoint(int nationalCode); } 对于每个子公司Web服务,我实现了一个inheritance此基类并定义自己的GetPoint方法的类。 public class Company1 { //implement own GetPoint method (call a web service). } 至 public class CompanyN { //implement own GetPoint method (call a web service). } 所以,这是我的网络方法: [WebMethod] public long MyCollector(string nationalCode) { […]

参考分配和阅读primefaces操作?

我发现了几个关于同一主题的问题,但与一般变量(值和引用类型)有关。 这个问题的接受答案是: CLI规范的第12.6.6节的分区I指出:“符合要求的CLI应保证当对位置的所有写访问都是相同大小时,对正确对齐的内存位置的读写访问权限不大于本机字大小是primefaces的“。 引用变量(即类)是指针,等于本机字大小,但我有几个疑问: 参考是否保证在正确对齐的内存位置? 我不明白最后一部分。 这是什么意思? “…当对一个位置的所有写访问都是相同的大小时。” 简而言之,obj2保证在以下代码的循环的每次迭代中都有效吗? class MyClass { private OtherClass m_Object; void Thread1() { while(true) { OtherClass obj1 = new OtherClass(); m_Object = obj1; } } void Thread2() { while (true) { OtherClass obj2 = m_Object; // Is obj2 guaranteed to be valid? obj2.Check(); } } }

互锁和记忆障碍

我有一个关于以下代码示例的问题( m_value不是volatile,每个线程都在一个单独的处理器上运行) void Foo() // executed by thread #1, BEFORE Bar() is executed { Interlocked.Exchange(ref m_value, 1); } bool Bar() // executed by thread #2, AFTER Foo() is executed { return m_value == 1; } 在Foo()中使用Interlocked.Exchange是否保证在执行Bar()时,我会看到值“1”? (即使该值已经存在于寄存器或缓存行中?)或者在读取m_value的值之前是否需要设置内存屏障? 另外(与原始问题无关),声明一个volatile成员并通过引用InterlockedXX方法传递它是合法的吗? (编译器警告通过引用传递volatile,所以在这种情况下我应该忽略警告吗?) 请注意 ,我不是在寻找“更好的做事方式”,所以请不要发布建议完全替代方式(“使用锁定”等)的答案,这个问题来自于纯粹的兴趣..

可以在后台线程中运行GC.Collect吗?

在这个SO答案之后 ,我正在做: ThreadPool.QueueUserWorkItem( delegate { GC.Collect(); GC.WaitForPendingFinalizers(); GC.Collect(); }); 我的目标是在关闭一个包含大量图像/ PictureBox控件的大型WinForms表单后进行垃圾收集运行,以确保我的内存中不再有图像。 (我确实相信我遵循Jon Skeet的指示 )。 我在后台线程中这样做是为了尝试让我的UI响应。 我的问题: 它是否为我在后台线程中进行垃圾收集带来了什么好处? 或者它实际上使我的应用程序更慢/挂起更长?

如何调用一个在线程中接受多个参数的方法?

我正在构建一个C#Desktop应用程序。 如何调用在线程中接受多个参数的方法。 我有一个名为Send的方法(字符串arg1,字符串arg2,字符串arg3),我需要使用一个名为SendingThread的线程调用此方法。 任何人都可以帮忙吗? 任何帮助都感激不尽。

C#BackgroundWorker的文化

我想为整个应用程序设置文化。 我尝试了以下方法: Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(wantedCulture); Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture(wantedCulture); Application.CurrentCulture = CultureInfo.CreateSpecificCulture(wantedCulture); 它适用于当前线程,但稍后我创建并启动后台工作线程。 当我创建worker时,当前线程使用wantedCulture执行,但工作线程将使用我的计算机文化运行。 为整个应用程序设置文化的任何想法?

将CancellationToken传递给Task Class构造函数有什么用?

下面是一个示例代码,它创建一个模拟长时间运行进程的新任务。任务没有太多关于取消function。我使用取消令牌来取消任务,代码对我来说运行正常。 CancellationTokenSource CTS= new CancellationTokenSource(); Task PTask = new Task(() => { while (true) { if (!CTS.Token.IsCancellationRequested) { Thread.Sleep(5000); } else{Console.WriteLine(“Thread Cancelled”);break;} } return true; }, CTS.Token, TaskCreationOptions.None); PTask.Start(); Console.WriteLine(“Hit Enter to cancel the Secondary thread you have started”); Console.ReadLine(); CTS.Cancel(); System.Console.WriteLine(PTask.Result); } } 但是我无法理解的是将令牌参数(CTS.Token)传递给任务构造函数。传递参数的实际用途是什么,即使我没有将令牌传递给构造函数也可以实际取消任务。 下面是一个稍微修改过的版本,没有令牌参数。 CancellationTokenSource CTS= new CancellationTokenSource(); Task PTask = new Task(() […]