动态线程如何帮助解决我的性能问题
本文关键字:解决 我的 性能 问题 帮助 线程 何帮助 动态 | 更新日期: 2023-09-27 18:13:32
。使用的.NET Framework:3.5和Visual Studio 2008
我有一个在不同数据库上执行某些更新的方法。
现在我有一个"foreach循环",其中调用了用于执行数据库更新的函数。循环根据数据库的数量执行。客户端服务器中可能有700多个数据库。因此,循环将执行700次,这需要超过10个小时,这是一个很大的性能问题。
我们遇到的一个解决方案是动态线程创建。
例如:如果我们有100个数据库,然后将其拆分为10个线程,具有1到10个数据库的方法将由线程1处理,接下来10到20个数据库调用将由线程2处理……就像使用10个线程更新的100个数据库一样。
有谁能帮我解决这个问题吗。如果你还有其他合适的想法,请分享。。。
您可以使用类似的工作线程池
public void DoWork()
{
// queue in a loop
System.Threading.ThreadPool.QueueUserWorkItem(new System.Threading.WaitCallback(YourDatabaseWork));
}
private void YourDatabaseWork(Object state)
{
// Insert code to perform a long task.
}
通过这种方式,你可以对你想做的每一项工作进行排队(假设你不需要太多内存就可以一次完成所有工作(。有一定数量的工作线程可用,所有其他线程都将被放入队列中。因此,您应该能够简单地一次"启动"所有线程,并且每次完成一个现有的工作线程时,都会处理一个新的排队项目。
您可以在此处阅读更多信息:http://msdn.microsoft.com/en-us/library/h4732ks0.aspx
有关如何在需要时使用输入参数,您可以阅读此处:http://msdn.microsoft.com/en-us/library/4yd16hza.aspx
您的问题最好通过异步来解决。如果你的更新工作是IO绑定的(数据库更新命令通常是(,那么你的700个线程大部分时间都会坐在那里等待数据库更新完成。解决方案是异步执行这些更新,然后线程池将拥有足够多的线程。
您可以同时启动所有更新,然后等待任务完成。如果您的更新更复杂,并且涉及执行多个查询,请使每个查询异步执行,并将结果设为await
。下面是一个使用.net 4.5:的简单示例
public async Task UpdateDatabses(List<string> databses)
{
List<Task> updateTasks = new List<Task>();
foreach (var db in databses)
{
updateTasks.Add(UpdateDatabase(db));
}
// asynchronously wait for all the tasks to complete
await Task.WhenAll(updateTasks);
}
public async Task UpdateDatabase(string databse)
{
await /* Update the database */
}
更新
对于。NET 3.5,您需要为安装任务并行Librbary。NET 3.5包。我们需要Task.WhenAll
或Task.ConitnueWhenAll
扩展方法,但我找不到的任何版本。NET 3.5。所以我自己写了一篇:
public static class Extensions
{
/// <summary>
/// Returns a task that completes when all the passed tasks are completed
/// </summary>
public static Task WhenAll(IEnumerable<Task> tasks)
{
var tcs = new TaskCompletionSource<object>();
var remainingTasks = tasks.ToList();
int count = remainingTasks.Count();
var exceptions = new List<Exception>();
foreach (var task in remainingTasks)
{
task.ContinueWith(t =>
{
if (Interlocked.Decrement(ref count) == 0)
{
foreach (var task1 in remainingTasks)
{
if (task1.IsFaulted)
{
exceptions.Add(task1.Exception);
}
}
if (exceptions.Any())
{
tcs.SetException(new AggregateException(exceptions));
}
else
{
tcs.SetResult(null);
}
}
});
}
return tcs.Task;
}
}
然后,您应该能够将代码更改为以下内容:
public Task UpdateDatabses(List<string> databses)
{
List<Task> updateTasks = new List<Task>();
foreach (var db in databses)
{
updateTasks.Add(UpdateDatabase(db));
}
return Extensions.WhenAll(updateTasks);
}
public Task UpdateDatabase(string databse)
{
return null; /* Update the database using a Task returninng asynchronous operation*/
}