0

私たちのアプリケーションにメモリリークがあるかどうかをテストし、リクエストを処理している間にメモリ使用量が増加しすぎているかどうかを監視する必要があります。 私はapi/webserviceメソッドへの複数の同時呼び出しを行うためにいくつかのコードを開発しようとしています。このapiメソッドは非同期ではなく、操作を完了するまでに時間がかかります。c#webserviceをロードする方法

私はTasks、Threads、およびParallelismについて多くの研究を行ってきましたが、これまでは運がありませんでした。問題は、以下のすべてのソリューションを試した後でも、結果は常に同じです。その時点で2つの要求しか処理されていないようです。

が試み:

- >ループのためのシンプルな内部タスクを作成し、としてTaskCreationOptions.LongRunning

でそれらを設定せずに、それらを開始 - >ループのためのシンプルな内部スレッドを作成し、でとすることなく、それらを開始します優先度の高い

- >ループのためのシンプルでアクションのリストを作成し、使用してそれらを開始

Parallel.Foreach(list, options, item => item.Invoke) 

- > Parallel.Forループ内で直接実行(以下)

- > MaxParallelism最大スレッド

に対して異なる値でみた - - >オプションとTaskScheduler

とないTPL方法を実行>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 

私が知る限り、サーバー側に制限はありません。私はParallel/Multitaskingの世界では比較的新しいです。これを行う他の方法はありますか?何か不足していますか?

(私はすべてのコードを簡略化するために単純化しましたが、提供されたコードは上記のシナリオを描写するのに十分であると考えています。何らかの関連性があるコードがあれば教えてください。編集して投稿することもできます)

ありがとうございます!

EDIT1:サーバーのログで2つずつリクエストが受信されていることを確認しました。実際に送信することに関連しています。 フレームワークが要求/接続をどのように管理するかは、ネットワークの問題または制限事項ですか?またはネットワークで何か(ネットとは無関係)?

EDIT2:忘れて、それはSOAP Webサービスです。

EDIT3:送信するプロパティ(データ内)の1つは、リクエストごとに変更する必要があります。

EDIT4:リクエストの各ペアの間には、関連する場合は常に〜25秒の間隔があることに気付きました。

+0

[Webテスト](https://msdn.microsoft.com/en-us/library/ms182536(v= versus90).aspx)を使用してみましたか?特定のリクエストを記録し、[VS負荷テスト](https://www.visualstudio.com/en-us/docs/test/performance-testing/getting-started/getting-started-パフォーマンステストあり)。 – G0dsquad

+0

ありがとう、私はそれを試していない、それを見てみましょう。しかし、私はWebメソッドだけをテストする必要があります。UIはありません。 Webテストを使用してそれを達成することは可能ですか?同時に、それを同時に実行することは可能ですか?なぜなら私はサーバーに同時にアクセスする要求が必要なのです。 –

+0

もちろん、WebMethodにHTTPエンドポイントがある場合は、Webテストでリクエスト(データPOSTなど)を記録できます。次に、50人の並列ユーザーに対して、現実的な思考時間で10分間、負荷テストを設定することができます。 – G0dsquad

答えて

2

私は車輪の再発明だけ既存のソリューションのいずれかを使用しないようお勧めします:

  1. ほとんど当然の選択:あなたのVisual Studioのライセンスは、最も可能性の高いあなたが「勝った、あなたはテストフレームワークをロードするMSを使用することができます許可する場合トンでも単一のコード行を記述する必要があります:How to: Create a Web Service Test
  2. SoapUIは、フリーでオープンソースのWebサービスのテストツールですSOAPUIは適切ではない、いくつかの理由のために(つまり、あなたが負荷を実行する必要がある場合は、それはいくつかの限られたload testing capabilities
  3. を持っていますいくつかのホストまたはヨーのクラスターモードでのテストより高度なレポートが必要)をサポートするフリーでオープンソースのマルチプロトコル負荷テストツールApache JMeterを使用することができます。
+0

返信いただきありがとうございます!私は質問を編集しました。別のこともあります:リクエストごとに、私が送るオブジェクトのプロパティの1つを変更する必要があります。これらのツールでこれを達成できますか? (私はまだドキュメントを読んでいます) –

+0

Visual Studioでは、.NETフレームワークのすべての機能を持つ3つのオプションがすべて可能です。SoapUIとJMeterには[Groovy言語](https://www.blazemeter。 com/blog/groovy-new-black)をスクリプトソリューションとして使用することもできます.JMeterでは、GUIを使用してすべての設定を行うことができます(データをランダム化したり、CSVファイル、データベースなどから取得できます)。 –

+0

私はそれをより強力なCPUの方法でサーバ上で実行することで動作させることができました。私のコンピュータは、私が望んだ数のスレッドを起動することができなかったようです。しかし、これらはいくつかの良い解決策です、私は次の時にそれを念頭に置いておきます。ありがとう! –

1

独自のプロジェクトを作成することなく、負荷テストを作成するための良い解決策は、あなたが、パラメータ、ヘッダーを投稿することができますそれは小さなテストのために無料でこのサービスhttps://loader.io/targets

を使用して...、あなたは素敵な報告を持っています。

+0

比較的大きなテストを行い、テスト環境はインターネットに公開されていません。私はより柔軟な/制御可能なものを探していました。そのため私たちは独自のテストプロジェクトを作ろうとしています。 –

関連する問題