首页 \ 问答 \ 重新启动正常的线程(Restarting normal Threads)

重新启动正常的线程(Restarting normal Threads)

假设我想要做的是验证一百万个字符串,每个验证需要几秒钟。

我的方法:

我有一个像这样声明的线程数组:

Thread[] workers = new Thread[50];

我没有数组中的所有字符串,它们通过一些计算得到,然后当我开始进程时没有全部字符串,但是我有一个返回下一个字符串的方法:

public string next()
{
  //my code
}

我已经能够像这样运行所有50个线程:

for (int x = 0; x < 50; x++)
{
workers[x] = new Thread(new ParameterizedThreadStart(myMethod));
workers[x].Start(next());
}

它迅速启动所有50个线程“同时”,然后我的日志(由myMethod提供)几乎同时获得50个响应(1〜1.5秒)

我怎样才能让每一个刚完成的线程再次运行,并考虑到Thread类不暴露任何事件或类似的东西?

注:我已经完成了一些性能测试,我更喜欢使用常规线程而不是BackgroundWorkers。

在.net 3.5中使用C#。


Let's say that what I want to do is to validate one million strings, and each validation takes a couple of seconds.

My approach:

I have an array of threads declared like this:

Thread[] workers = new Thread[50];

I don't have all strings in an array, they are got through some calculations, then I don't have all of them when I start the process, but I have a method that returns the next one:

public string next()
{
  //my code
}

I've been able to run all the 50 threads like this:

for (int x = 0; x < 50; x++)
{
workers[x] = new Thread(new ParameterizedThreadStart(myMethod));
workers[x].Start(next());
}

Which swiftly starts all 50 threads "at the same time" and then my log (fed by myMethod) gets 50 responses almost at the same time (1~1.5 second)

How do I get every thread that has just completed to run again with the next string taking into account that the Thread class doesn't expose any event or anything similar ?

Note: I have done some performance tests, and I prefer to use the regular Threads rather than BackgroundWorkers.

Using C# in .net 3.5.


原文:https://stackoverflow.com/questions/3893624
更新时间:2023-09-13 18:09

最满意答案

什么是可以接受的是非常主观的,但如果你想做适当的数据访问,我建议你不要使用存储库模式,因为随着你的应用程序变得越来越复杂,它就会崩溃。

最大的原因是最小化数据库访问。 因此,例如查看您的存储库并注意GetUser()方法。 现在退出代码并考虑应用程序将如何使用。 现在考虑一下您多长时间无需额外的数据就可以从用户表中请求数据。 除非您正在创建基本的数据录入应用程序,否则答案几乎总是“很少”。

你说你的应用程序会显示很多网格。 该网格中的数据是什么? 我假设(不知道您的应用程序域)网格将用户数据与其他与该用户相关的信息组合在一起。 如果是这样的话,你如何使用你的仓库?

一种方法是单独调用每个存储库的方法,如下所示:

var user = userRepository.GetUser("KallDrexx");
var companies = companyRepository.GetCompaniesForUser(user.Id);

现在这意味着你有2个数据库调用,真正应该只有一个。 随着屏幕变得越来越复杂,这会导致数据库点击次数增加和增加,并且如果您的应用程序获得大量流量,则会导致性能问题。 在存储库模式中执行此操作的唯一方法是将特殊方法添加到存储库以执行特定查询,如:

public class UserRepository
{
    public User GetUser(string userName)
    {
        // GetUser code          
    }

    public User GetUserWithCompanies(string userName)
    {
        // query code here
    }
}

那么现在如果您需要用户并在一个查询中说出他们的联系人数据会发生什么。 现在,您必须将另一种方法添加到您的用户存储库。 现在说你需要做另一个查询,它也返回每个公司的客户数量,所以你需要添加另一个方法(或者添加一个可选参数)。 现在说你想添加一个查询,返回所有公司以及他们包含的用户。 现在你需要一个新的查询方法,但是你会把它放在User存储库或Company存储库中吗? 你如何跟踪它所处的位置,并在GetUserWithCompany需要时在GetUserWithCompanyGetCompanyWithUsers之间进行选择?

从那时起,所有东西都变得非常复杂,这就是让我放弃存储库模式的情况。 我现在所做的数据访问是创建单独的查询和命令类,每个类代表1(且只有1个)查询或数据更新命令到数据库。 每个查询类都会返回一个视图模型,该视图模型仅包含我需要的特定用户使用场景的数据。 还有其他的数据访问模式也可以工作(规范模式,一些好的开发人员甚至说你应该在控制器中进行数据访问,因为EF 你的数据访问层)。

成功完成数据访问的关键是做好规划。 你知道你的屏幕会是什么样子吗? 你知道用户如何使用你的系统吗? 你知道所有的数据实际上将在每个屏幕上? 如果其中任何一个的答案都是否定的,那么您需要退后一步并忘记数据层,因为数据层是(或者应该是一个好的应用程序),这取决于应用程序实际上将如何使用时,UI和屏幕不应该依赖于数据层的设计方式。 如果您在开发数据访问时不考虑您的用户界面需求和用户使用场景,那么您的应用程序将无法很好地扩展并且性能不佳。 有时候,如果你的网站规划不是很大,那么这不是问题,但是记住这些事情永远不会让人感到伤心。


What's acceptable is pretty subjective, but if you want to do proper data access I suggest you do NOT use the repository pattern, as it breaks down as your application gets more complex.

The biggest reason is minimizing database access. So for example look at your repository and notice the GetUser() method. Now take a step back from the code and think about how your application is going to be used. Now think about how often you are going to request data from the user table without any additional data. The answer is almost always going to be "rarely" unless you are creating a basic data entry application.

You say it your application will show a lot of grids. What data is in that Grid? I'm assuming (without knowing your application domain) that the grids will combine user data with other information that's relevant for that user. If that's the case, how do you do it with your repositories?

One way is to call on each repository's method individually, like so:

var user = userRepository.GetUser("KallDrexx");
var companies = companyRepository.GetCompaniesForUser(user.Id);

This now means you have 2 database calls for what really should be just one. As your screens get more and more complex, this will cause the number of database hits to increase and increase, and if your application gets significant traffic this will cause performance issues. The only real way to do this in the repository pattern is to add special methods to your repositories to do that specific query, like:

public class UserRepository
{
    public User GetUser(string userName)
    {
        // GetUser code          
    }

    public User GetUserWithCompanies(string userName)
    {
        // query code here
    }
}

So now what happens if you need users and say their contact data in one query. Now you have to add another method to your user repository. Now say you need to do another query that also returns the number of clients each company has, so you need to add yet another method (or add an optional parameter). Now say you want to add a query that returns all companies and what users they contain. Now you need a new query method but then comes the question of do you put that in the User repository or the Company repository? How do you keep track of which one it's in and make it simple to choose between GetUserWithCompany and GetCompanyWithUsers when you need it later?

Everything gets very complex from that point on, and it's those situations that have made me drop the repository pattern. What I do now for data access is I create individual query and command classes, each class represents 1 (and only 1) query or data update command to the database. Each query class returns a view model that only contains the data I need for one specific user usage scenario. There are other data access patterns that will work too (specification pattern, some good devs even say you should just do your data access in your controllers since EF is your data access layer).

The key to doing data access successfully is good planning. Do you know what your screens are going to look like? Do you know how users are going to use your system? Do you know all the data that is actually going to be on each screen? If the answer to any of these is no, then you need to take a step back and forget about the data layer, because the data layer is (or should be for a good application) determined based on how the application is actually going to be used, the UI and the screens should not be dependent on how the data layer was designed. If you don't take your UI needs and user usage scenarios into account when developing the data access, your application will not scale well and will not be performant. Sometimes that's not an issue if you don't plan on your site being big, but it never hurts to keep those things in mind.

相关问答

更多
  • 如果NumberOfFollowers是用户的属性,它肯定应该在User类上,而不是在存储库上。 存储库仅负责获取/放置数据。 这里是我最喜欢的EF执行库: http://www.codeproject.com/KB/database/ImplRepositoryPatternEF.aspx 这个很棒,非常完整,并且有很多功能。 If NumberOfFollowers is a property of a User, it should definitely be on the User class, n ...
  • 最简单的方法是在存储库提供程序中处理缓存。 这样你就不必在你的应用程序的其余部分中修改任何代码; 数据不会被存储在缓存中,而是将数据从缓存而不是存储库中提取出来。 所以,我将创建一个接口,控制器用来与后端进行通信,在实现时我会添加缓存逻辑。 将其全部放在带有DI的好弓上,您的应用程序将被设置为轻松测试。 The easiest way would be to handle caching in your repository provider. That way you don't have to chan ...
  • 通常,在实现存储库模式时,您可以执行以下操作: public class ReadOnlyRepository : IReadOnlyRepository where TEntity : class { // Read-only methods here } public class Repository : ReadOnlyRepository, IRepository where TEntity : class { ...
  • 什么是可以接受的是非常主观的,但如果你想做适当的数据访问,我建议你不要使用存储库模式,因为随着你的应用程序变得越来越复杂,它就会崩溃。 最大的原因是最小化数据库访问。 因此,例如查看您的存储库并注意GetUser()方法。 现在退出代码并考虑应用程序将如何使用。 现在考虑一下您多长时间无需额外的数据就可以从用户表中请求数据。 除非您正在创建基本的数据录入应用程序,否则答案几乎总是“很少”。 你说你的应用程序会显示很多网格。 该网格中的数据是什么? 我假设(不知道您的应用程序域)网格将用户数据与其他与该用户相 ...
  • 使用存储库模式(据我所知)的主要目标是将您的应用程序与使用特定数据访问层分离。 你没有在这里做过,因为你创建我可以看到你的EmployeeRepository类没有实现一个接口。 你真的想拥有像EmployeeRepository : IEmployeeRepository这样的东西EmployeeRepository : IEmployeeRepository 然后,在您的Controller代码中,您可以传递IEmployeeRepository而不是与EmployeeRepository具体地一起工作 ...
  • 如果通过IoC将上下文对象生命周期设置为Per HttpRequest,则可以将每个HttpRequest和每个.SaveChanges()执行所有数据库调用作为一个事务。 而不是每个存储库的私有上下文,将上下文注入存储库。 在结构图的情况下, For().LifecycleIs(new HybridLifecycle()).Use(c=> new DbContext()); If you have your context object life cycle set to P ...
  • 有一个实体框架Nerddinner.com示例: http://nerddinner.codeplex.com/releases/view/45621 There is an Entity Framework Nerddinner.com sample: http://nerddinner.codeplex.com/releases/view/45621
  • EF中定义的实体是持久性模型 ,即它们模拟使用什么结构保存的数据。 应用程序通常有一个模型,可以模拟真实的业务问题和解决方案,即行为。 存储库接收此应用程序对象,然后从中提取存储需求所需的任何信息。 大多数情况下,2个模型(应用程序和持久性)将类似很多,因为简单的事情是相同的,但在许多情况下由于意图存在差异(应用程序模型意图是模型行为,持久性意图是模型存储)。 加载保存的数据时,存储库会从其保存的表单中重新创建应用程序对象,因此它会将持久性模型映射到应用程序模型。 如果模型非常简单,那么您可以直接使用EF实 ...
  • 我更喜欢让我的Repository在内部对我自己的类进行映射。 所以我从我的存储库返回的不是LinqToSql类,而是我自己的类。 然后,我将返回的类数据映射到每个视图的模型中。 所以它看起来像: LinqToSQL类 - > MyClass(此时从Repository输出) - >(控制器映射到特定视图的模型)MyModel。 确保始终为每个视图创建模型。 您可以使用您的存储库返回的内容,但这是一个捷径,并将其映射到自己的视图模型将在未来获得回报。 I prefer to have my Reposito ...
  • 是的,这意味着有两个DbContext实例。 更好的是在Database类中有一个DbContext实例,并在所有方法中使用此实例。 public class Database : IDatabase, IDisposeable { private Entities db; public Database() { db = new Entities() } ... some other methods ... public bool VerifyUs ...

相关文章

更多

最新问答

更多
  • 获取MVC 4使用的DisplayMode后缀(Get the DisplayMode Suffix being used by MVC 4)
  • 如何通过引用返回对象?(How is returning an object by reference possible?)
  • 矩阵如何存储在内存中?(How are matrices stored in memory?)
  • 每个请求的Java新会话?(Java New Session For Each Request?)
  • css:浮动div中重叠的标题h1(css: overlapping headlines h1 in floated divs)
  • 无论图像如何,Caffe预测同一类(Caffe predicts same class regardless of image)
  • xcode语法颜色编码解释?(xcode syntax color coding explained?)
  • 在Access 2010 Runtime中使用Office 2000校对工具(Use Office 2000 proofing tools in Access 2010 Runtime)
  • 从单独的Web主机将图像传输到服务器上(Getting images onto server from separate web host)
  • 从旧版本复制文件并保留它们(旧/新版本)(Copy a file from old revision and keep both of them (old / new revision))
  • 西安哪有PLC可控制编程的培训
  • 在Entity Framework中选择基类(Select base class in Entity Framework)
  • 在Android中出现错误“数据集和渲染器应该不为null,并且应该具有相同数量的系列”(Error “Dataset and renderer should be not null and should have the same number of series” in Android)
  • 电脑二级VF有什么用
  • Datamapper Ruby如何添加Hook方法(Datamapper Ruby How to add Hook Method)
  • 金华英语角.
  • 手机软件如何制作
  • 用于Android webview中图像保存的上下文菜单(Context Menu for Image Saving in an Android webview)
  • 注意:未定义的偏移量:PHP(Notice: Undefined offset: PHP)
  • 如何读R中的大数据集[复制](How to read large dataset in R [duplicate])
  • Unity 5 Heighmap与地形宽度/地形长度的分辨率关系?(Unity 5 Heighmap Resolution relationship to terrain width / terrain length?)
  • 如何通知PipedOutputStream线程写入最后一个字节的PipedInputStream线程?(How to notify PipedInputStream thread that PipedOutputStream thread has written last byte?)
  • python的访问器方法有哪些
  • DeviceNetworkInformation:哪个是哪个?(DeviceNetworkInformation: Which is which?)
  • 在Ruby中对组合进行排序(Sorting a combination in Ruby)
  • 网站开发的流程?
  • 使用Zend Framework 2中的JOIN sql检索数据(Retrieve data using JOIN sql in Zend Framework 2)
  • 条带格式类型格式模式编号无法正常工作(Stripes format type format pattern number not working properly)
  • 透明度错误IE11(Transparency bug IE11)
  • linux的基本操作命令。。。