我需要测试我们的应用程序中是否有任何内存泄漏,并监视内存使用量在处理请求时是否增加太多。 我正在尝试开发一些代码,以便对我们的api/webservice方法进行多个同时调用。此api方法不是异步的,需要一些时间才能完成操作。c#如何加载测试Web服务
我已经做了大量关于任务,线程和并行的研究,但到目前为止我还没有运气。问题是,即使在尝试了所有下面的解决方案之后,结果总是相同的,但它似乎只处理当时的两个请求。
尝试:
- >内创建一个简单的任务和循环使用和不使用TaskCreationOptions.LongRunning
设置它们启动它们 - >内创建一个简单的线程循环,有和没有他们开始高优先级
- >创建的for循环的一个简单的动作列表,并使用启动它们
Parallel.Foreach(list, options, item => item.Invoke)
- >直接一个的Parallel.For循环(下面)
内部运行 - >运行有和没有选项和TPL的TaskScheduler方法
- >有用于MaxParallelism和最大线程
不同的值试图- >也检查了this post,但它也没有帮助。 (我可能会错过什么?)
- >检查一些其他帖子在这里在Stackoverflow,但与F#解决方案,我不知道如何正确地将它们转换为C#。 (我从来没有使用F#...)
(从msdn拍摄任务调度器类)
这里的基本结构,我有:
public class Test
{
Data _data;
String _url;
public Test(Data data, string url)
{
_data = data;
_url = url;
}
public ReturnData Execute()
{
ReturnData returnData;
using(var ws = new WebService())
{
ws.Url = _url;
ws.Timeout = 600000;
var wsReturn = ws.LongRunningMethod(data);
// Basically convert wsReturn to my method return, with some logic if/else etc
}
return returnData;
}
}
sealed class ThreadTaskScheduler : TaskScheduler, IDisposable
{
// The runtime decides how many tasks to create for the given set of iterations, loop options, and scheduler's max concurrency level.
// Tasks will be queued in this collection
private BlockingCollection<Task> _tasks = new BlockingCollection<Task>();
// Maintain an array of threads. (Feel free to bump up _n.)
private readonly int _n = 100;
private Thread[] _threads;
public TwoThreadTaskScheduler()
{
_threads = new Thread[_n];
// Create unstarted threads based on the same inline delegate
for (int i = 0; i < _n; i++)
{
_threads[i] = new Thread(() =>
{
// The following loop blocks until items become available in the blocking collection.
// Then one thread is unblocked to consume that item.
foreach (var task in _tasks.GetConsumingEnumerable())
{
TryExecuteTask(task);
}
});
// Start each thread
_threads[i].IsBackground = true;
_threads[i].Start();
}
}
// This method is invoked by the runtime to schedule a task
protected override void QueueTask(Task task)
{
_tasks.Add(task);
}
// The runtime will probe if a task can be executed in the current thread.
// By returning false, we direct all tasks to be queued up.
protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued)
{
return false;
}
public override int MaximumConcurrencyLevel { get { return _n; } }
protected override IEnumerable<Task> GetScheduledTasks()
{
return _tasks.ToArray();
}
// Dispose is not thread-safe with other members.
// It may only be used when no more tasks will be queued
// to the scheduler. This implementation will block
// until all previously queued tasks have completed.
public void Dispose()
{
if (_threads != null)
{
_tasks.CompleteAdding();
for (int i = 0; i < _n; i++)
{
_threads[i].Join();
_threads[i] = null;
}
_threads = null;
_tasks.Dispose();
_tasks = null;
}
}
}
而且测试代码本身:
private void button2_Click(object sender, EventArgs e)
{
var maximum = 100;
var options = new ParallelOptions
{
MaxDegreeOfParallelism = 100,
TaskScheduler = new ThreadTaskScheduler()
};
// To prevent UI blocking
Task.Factory.StartNew(() =>
{
Parallel.For(0, maximum, options, i =>
{
var data = new Data();
// Fill data
var test = new Test(data, _url); //_url is pre-defined
var ret = test.Execute();
// Check return and display on screen
var now = DateTime.Now.ToString("HH:mm:ss");
var newText = $"{Environment.NewLine}[{now}] - {ret.ReturnId}) {ret.ReturnDescription}";
AppendTextBox(newText, ref resultTextBox);
}
}
public void AppendTextBox(string value, ref TextBox textBox)
{
if (InvokeRequired)
{
this.Invoke(new ActionRef<string, TextBox>(AppendTextBox), value, textBox);
return;
}
textBox.Text += value;
}
而我得到的结果基本上是这样的:
[10:08:56] - (0) OK
[10:08:56] - (0) OK
[10:09:23] - (0) OK
[10:09:23] - (0) OK
[10:09:49] - (0) OK
[10:09:50] - (0) OK
[10:10:15] - (0) OK
[10:10:16] - (0) OK
etc
据我所知,服务器端没有限制。我对并行/多任务处理领域相对陌生。有没有其他方法可以做到这一点?我错过了什么吗?我简化了所有代码的清晰性,我相信所提供的代码足以描述上述场景。我也没有发布应用程序代码,但它是一个简单的WinForms屏幕,只是为了调用和显示结果。如果任何代码有某种相关性,请告诉我,我可以编辑并发布。)
在此先感谢!
EDIT1:我检查了服务器日志,它收到的请求两个两个,所以这确实是有关发送它们,没有收到。 它可能是一个与框架如何管理请求/连接有关的网络问题/限制吗?或者与网络有什么关系(与.net无关)?
编辑2:忘了提及,它是一个SOAP web服务。
EDIT3:我发送的一个属性(内部数据)需要为每个请求更改。编辑4:我注意到每对请求之间总是有25秒的时间间隔,如果相关的话。
您是否尝试过使用[Web Test](https://msdn.microsoft.com/en-us/library/ms182536(v = vs.90).aspx)?您可以记录特定的请求,然后将其作为[VS Load Test]的一部分运行(https://www.visualstudio.com/en-us/docs/test/performance-testing/getting-started/getting-started-与性能测试)。 – G0dsquad
谢谢,我没有试过,会看看它。但我只需要测试webmethod,没有UI。使用Web测试可以实现吗?是否可以同时运行很多次?因为我需要同时访问服务器的请求,或者最接近服务器的请求。 –
当然,如果WebMethod具有HTTP端点,则可以使用Web测试记录请求(例如数据POST)。然后,您可以配置负载测试,以10分钟的时间用真实的思考时间说50个并行用户。 – G0dsquad