Tag: multithreading

在C#中是否有一个很好的方法可以在给定的线程上抛出exception

我想写的代码是这样的: void MethodOnThreadA() { for (;;) { // Do stuff if (ErrorConditionMet) ThrowOnThread(threadB, new MyException(…)); } } void MethodOnThreadB() { try { for (;;) { // Do stuff } } catch (MyException ex) { // Do the right thing for this exception. } } 我知道我可以让线程B以线程安全的方式定期检查线程A是否设置了一个标志,但这会使代码更复杂。 有没有更好的机制可供我使用? 这是一个更加充实的定期检查示例: Dictionary exceptionDictionary = new Dictionary(); void ThrowOnThread(Thread thread, […]

发布模式下的无限循环

当我在调试模式下运行以下代码时,它将成功完成并退出。 但是,如果我在发布模式下运行以下代码,它将陷入无限循环而永远不会完成。 static void Main(string[] args) { bool stop = false; new Thread(() => { Thread.Sleep(1000); stop = true; Console.WriteLine(“Set \”stop\” to true.”); }).Start(); Console.WriteLine(“Entering loop.”); while (!stop) { } Console.WriteLine(“Done.”); } 哪种优化导致它陷入无限循环?

使用Task.WaitAll()来处理等待的任务?

理想情况下,我想要做的是使用非阻塞模式延迟任务,然后等待所有任务完成。 我试图添加Task.Delay返回的任务对象然后使用Task.WaitAll但似乎这没有用。 我该如何解决这个问题? class Program { public static async void Foo(int num) { Console.WriteLine(“Thread {0} – Start {1}”, Thread.CurrentThread.ManagedThreadId, num); var newTask = Task.Delay(1000); TaskList.Add(newTask); await newTask; Console.WriteLine(“Thread {0} – End {1}”, Thread.CurrentThread.ManagedThreadId, num); } public static List TaskList = new List(); public static void Main(string[] args) { for (int i = 0; i Foo(idx))); […]

这是在C#中引发事件的有效模式吗?

更新 :为了让读者阅读此内容的好处,自.NET 4以来,由于自动生成事件的同步更改,锁定是不必要的,所以我现在就使用它: public static void Raise(this EventHandler handler, object sender, T e) where T : EventArgs { if (handler != null) { handler(sender, e); } } 并提出它: SomeEvent.Raise(this, new FooEventArgs()); 在阅读了Jon Skeet 关于multithreading的文章之后 ,我试图将他提倡的方法封装在一个像这样的扩展方法中引发事件(使用类似的通用版本): public static void Raise(this EventHandler handler, object @lock, object sender, EventArgs e) { EventHandler handlerCopy; lock (@lock) { handlerCopy = […]

如何正确地进行异步/并行数据库调用

我正在寻找处理多个数据库调用的正确方法,这些调用可能会同时运行。 查询仅针对使用在ASP.NET MVC应用程序中以编程方式组装到DataTable中的数据进行插入或合并的存储过程。 当然我已经看到了关于async和await一些信息,这似乎是我需要做的,但我对如何实现它没有清楚的理解。 一些信息表明这些调用仍然是顺序调用的,并且仍然会等待另一个调用完成。 这似乎毫无意义。 最后,我想要一个解决方案,允许我在完成最长程序所需的时间内运行所有查询。 我希望所有查询都能返回受影响的记录数(就像现在一样)。 这就是我现在要做的事情(这绝不是平行的): // Variable for number of records affected var recordedStatistics = new Dictionary(); // Connect to the database and run the update procedure using (var dbc = new SqlConnection(db.Database.Connection.ConnectionString)) { dbc.Open(); // Merge One procedure using (SqlCommand cmd = new SqlCommand(“MergeOneProcedure”, dbc)) { // 5 minute timeout […]

SwitchToThread与睡眠(1)

我想知道调用Thread.Sleep(1)和调用SwitchToThread之间的实际区别是什么(如果我们忽略它当前没有被BCL暴露)。 Joe Duffy在他的post中提到: “kernel32!SwitchToThread API没有出现Sleep(0)和Sleep(1)的问题。” (关于调度程序的行为) 为什么Sleep不会像SwitchToThread一样? 为什么存在这种差异,以及它有什么用呢? (如果有的话……)

从ProcessThread获取托管线程

在我们无法重现的生产环境中,我们会定期关闭Windows服务。 可能需要几个月才能再次发生。 我正在进行一些诊断尝试并帮助解决这个问题,我正在研究的一件事是在我们开始关闭应用程序后将事件添加到系统线程池60秒。 我们的应用程序应在10秒内完全关闭。 在这种情况下,我想跟踪流程的剩余运行线程到事件日志。 我可以使用System.Diagnostics.Process.GetCurrentProcess.Threads获取正在运行的线程。 这些线程对象具有本机Win32线程ID等。 我想知道是否有任何方法可以从这些线程ID返回到它们在当前进程中表示的任何托管线程。 我试图这样做的原因是因为我们的线程池和其他线程产生了我们给出了代表它们目的的名称,这将有助于将它们取回。

从多个工作线程更新UI(.NET)

我有一个我正在研究的宠物项目,它有多个工作线程。 将所有内容输出到控制台变得越来越难以遵循,因此我想开发一个每个线程有一个输出区域的UI。 我想知道线程向UI发送更新的最佳方式。 我有两个想法: 1)让每个线程在新数据可用时设置“DataUpdated”标志,并让UI定期检查新数据。 2)创建每个线程,回调到新的数据可用时要调用的UI Update(…)方法。 我目前倾向于(2)有两个原因:我不喜欢“检查”每个线程的想法,因为这是我的第一个multithreading应用程序,(2)似乎比它可能更简单。 我想知道: 在简单性和效率方面哪个选项更可取? 你有任何实施技巧(2)或类似的东西(即更多的事件驱动)?

模拟在C#中撕掉一个双

我正在使用32位计算机运行,并且我能够确认使用以下代码片段可以快速查看长值。 static void TestTearingLong() { System.Threading.Thread A = new System.Threading.Thread(ThreadA); A.Start(); System.Threading.Thread B = new System.Threading.Thread(ThreadB); B.Start(); } static ulong s_x; static void ThreadA() { int i = 0; while (true) { s_x = (i & 1) == 0 ? 0x0L : 0xaaaabbbbccccddddL; i++; } } static void ThreadB() { while (true) { ulong x […]

C#的使用语句是否中止?

我刚刚读完了“C#4.0 in a Nutshell”(O’Reilly),我认为这对于愿意转向C#的程序员来说是一本很好的书,但它让我感到疑惑。 我的问题是using语句的定义。 根据这本书(第138页), using (StreamReader reader = File.OpenText(“file.txt”)) { … } 恰好相当于: StreamReader reader = File.OpenText(“file.txt”); try { … } finally { if (reader != null) ((IDisposable)reader).Dispose(); } 但是,假设这是真的,并且此代码在单独的线程中执行。 此线程现在使用thread.Abort()中止,因此抛出ThreadAbortException并假设线程正好在初始化读取器之后和输入try..finally子句之前。 这意味着读者不会被处置! 一种可能的解决方案是以这种方式编码: StreamReader reader = null; try { reader = File.OpenText(“file.txt”); … } finally { if (reader != null) ((IDisposable)reader).Dispose(); } 这将是中止安全的。 […]