【问题标题】:c# am I handling multiple threads properlyc# 我是否正确处理多个线程
【发布时间】:2009-01-30 16:13:17
【问题描述】:

我有一个 winform 应用程序,它创建 5 个线程以连接到数据库并以非常慢的连接(某些查询需要 90 秒)从数据库中检索信息。每个线程都有自己的类实例,用于执行 sql 查询。当查询的数据被检索到时,主线程会收到运行查询的类触发的事件的通知。接收到事件后,主线程的各个组件都会更新,例如显示项目或只是保存数据以供以后使用的数据表。根据查询的信息类型,查询会以不同的间隔重复。

一切都很好......但我不开心。我觉得应该换一种方式,但我不确定是哪种方式。

以下是我目前如何设置每个线程:

string ConnectionString = @"Data Source=mySrv;Initial Catalog=myTbl;Connect Timeout=30;UID=sa;pwd=mypwd";


//thread #1    
 SQL_Requests ReasonRequests;
 Thread Reason_Thread;
 ReasonRequests = new SQL_Requests();
 ReasonRequests.ProcessFinished += new SQL_Requests.ProcessFinished(ReasonRequests_Completed);
 Reason_Thread = new Thread(ReasonRequests.ExecuteQuery);
 ReasonRequests.DBQueryString = "select * from ReasonTable where staralingment = goodalignment"
 ReasonRequests.DBConnection = ConnectionString;

//thread #2
SQL_Requests EventRequests; 
Thread Event_Thread;
EventRequests = new SQL_Requests();
EventRequests.ProcessFinished += new SQL_Requests.ProcessFinished(EventRequests_Completed);
Event_Thread= new Thread(EventRequests.ExecuteQuery);

EventRequests.DBQueryString = "select * from EventTable where somefield = somevalue"
EventRequests.DBConnection = ConnectionString;

每个 Thread.start 的间隔不同。

有什么建议吗?

【问题讨论】:

    标签: c# multithreading


    【解决方案1】:

    您应该看看执行查询的异步方法,而不是自己启动线程,即http://msdn.microsoft.com/en-ca/library/system.data.sqlclient.sqlcommand.beginexecutereader.aspx

    您提到您的连接速度很慢,是低带宽连接还是高延迟连接?如果由于带宽不足而导致数据返回缓慢,则触发多个查询只会使事情变慢。如果这只是一个延迟问题,一次执行多个查询可能会提高响应能力。

    如果您正在执行一组相关查询,您可能还需要考虑将它们分组到一个命令中,或者使用存储过程在服务器上对它们进行分组。您可以通过使用 SqlDataReader 上的 NextResult 方法来获取其他结果集。

    【讨论】:

    • 谁知道?你显然做到了。就在我开始认为我对这种语言有基本的了解时,有人走过来说你知道你不必拖它……我们这里有轮子!谢谢! – 布拉德(1 分钟前)
    【解决方案2】:

    如果您的线程通过非常慢的连接从同一服务器获取数据(这意味着有限的带宽是主要因素),您将不会通过使用多个线程获得任何收益。

    实际上,对所有数据提取操作使用单个线程可能会更好:

    • 一段时间后,您将获得部分数据,因此您可以使用该数据更新 UI。并行取可能会分割带宽,你会很长时间没有任何数据,最终结果会一个接一个地到达。这样一来,您的 UI 会显得反应迟钝。

    • 如果选择导致服务器上出现大量 I/O,则不让它们并行执行实际上可能会产生更好的吞吐量。考虑到其他操作也会在服务器上执行。

    恕我直言,您应该将提取保留在线程中以获得最佳的 UI 响应,但只使用一个。

    编辑:您在评论中声明提取可能需要不同的时间。如果您可以估计哪些查询将最快地完成传输,请先执行它们。当然仍然假设大部分时间是数据传输,而不是服务器上的查询执行。

    如果您无法估计查询需要多长时间,或者如果带宽不是唯一的限制,那么使用多线程当然最适合您。

    【讨论】:

    • 我将获得的是,用户可以根据返回的信息开始解释生成的图表。一些查询会在几秒钟内返回,而另一些则需要 90 秒
    • 问题仍然存在......我的多线程实现是否正确?还是有更优雅的方法。
    【解决方案3】:

    您想要这样做的典型原因是,如果 5 个数据库查询中的每一个都很长,并且通过并行运行它们可以获得一些性能提升。如果您不打算从这样做中获得性能提升,我会简单地使用 一个 线程来完成数据库工作并将其进度报告给 UI。

    如果并行处理有性能优势,我会使用内置线程池 (System.Threading.ThreadPool.QueueUserWorkItem)。除非您需要对线程进行更多控制,否则线程池非常适合“即发即弃”类型的操作。您将一个操作排队,完成后它会调用一个委托。

    【讨论】:

      【解决方案4】:

      在不知道细节的情况下,这也会在我的嘴里留下不好的味道。我确信它有效。是否危险取决于您的主类是否是线程安全的。听起来你需要做一些严肃的测试:当两个请求同时完成并且都只是用相同的数据做了一些事情时会发生什么。

      老实说,如果我要寻找一种“不同的方式”来做到这一点,我可能会跳过对数据库的多线程访问,让一个线程完成所有数据库工作,而工作线程则做任何额外的工作需要进行的工作(如果有),然后向主线程报告以进行数据库访问。

      【讨论】:

      • 谁知道?你显然做到了。就在我开始认为我对这种语言有基本的了解时,有人走过来说你知道你不必拖它……我们这里有轮子!谢谢!
      【解决方案5】:

      不要使用纯线程来开发并​​发软件,还请考虑任务并行。

      请阅读以下文章: http://blog.rednael.com/2009/02/05/ParallelProgrammingUsingTheParallelFramework.aspx http://blog.rednael.com/2009/03/16/ParallelFrameworkDownloadAndSupport.aspx

      这些是有关基本并行编程的文章,还包含对有关并行背景的其他文章的参考。包括 C# .Net 中的示例。此外,它还描述了一个轻量级的并行框架来处理任务。与其他一些框架相比,这个框架非常轻巧且易于使用。 阅读这些文章后,您应该能够使用并行性编写代码。

      问候, 马丁

      【讨论】:

        猜你喜欢
        • 2011-08-05
        • 2014-05-02
        • 1970-01-01
        • 1970-01-01
        • 2016-04-29
        • 2020-04-29
        • 2021-10-29
        • 1970-01-01
        • 2020-06-03
        相关资源
        最近更新 更多