2017-04-06 12 views
8

私たちがサポートしている古いプロジェクトがあり、マルチスレッドの可能性が最も高い問題があります。 問題のあるセクションを実行する前に、元の実装者がThread.sleepを実行して「修正」しました。 回避策は機能しますが、セクションがループ内にあるため、thread.sleepはセクションが終了するまでに複数の時間を追加します。アプリケーションを強制的にシングルスレッドとして実行する方法はありますか?

私たちは睡眠の値を低くして実験してきましたが、根本的な原因を見つけたいと思います。私たちの調査中に私たちは私たちが助けてくれると思ったところで私物のものにlockをやっていました。 追加のスレッドを生成する可能性のあるものを探しました。 いいえThread.startは使用せず、ThreadPoolを使用しません。 私たちを混乱させているのは、デバッグ中にメインスレッドが、誰がそれらを生成したか分からない約8つの他のスレッドの真ん中にあることです。 これはバックグラウンドスレッドなので、私が最初に考えたのはスレッドプールだと思っていましたが、コード内でそれについて言及しなかったので、

.net 2.0なのでAsyncsです。 これは大きなアプリケーションの一部ですので、Windowsサービスですが、簡単にデバッグできるようにCMDとして実行します。メインアプリケーション自体はWindowsフォームデスクトップアプリケーションです。 また、COM +コンポーネントが使用されている場合は、そのコンポーネントも使用されます。

の代わりに[STA]を試しました。 また前述のようにロックします。 MemoryBarrierも同様である。

問題は引き続き発生します。

この問題は、基本的にデータセットが破損していて、オブジェクトが存在してはいけないオブジェクトではnullです。 25-100回の繰り返しごとに1回発生するので、複製は簡単ではありませんが、この問題を再現しようとするテストを考案しました。

スレッドの問題の方向を私たちに指摘しています。

元の質問に戻る - これらの追加スレッドを作成することによって、誰がこのスレッドを作成できないようにすることができますか?

enter image description here

赤でマークされたスレッドに注意してください - これらは、バックグラウンドスレッドであり、限り、我々は、コードでそれらの言及を見ることができないよう。

スクリーンショットの疑わしいスレッドが、datasetの列をアクティブに変更しています。問題は - スレッドが実行している関数SetColValueOnRowを呼び出すメソッドは典型的なものであり、どのような種類のスレッドも使用しません。

このアプリケーションのCPUの親和性は1つのコア[元-周りの仕事の一部]

おかげ

編集に設定されています:データベースがOracle 12cのですが、私たちが直面している問題はに書き込む前に起こりますデータベース。 通常、データセットで発生するのは、テストの繰り返し回数が1回になるとレコード全体またはその列のいくつかが1回拭き取れることです。

+0

どのタイプのアプリケーション(winforms、service、...) – pm100

+0

これは大きなアプリケーションの一部なので、Windowsサービスですが、簡単にデバッグできるようにCMDとして実行します メインアプリケーション自体Windowsフォームデスクトップアプリケーションです。 – AngelicCore

+0

また、この問題を再現/デバッグする際には、この部分だけを実行し、残りのアプリケーションは実行しません。 – AngelicCore

答えて

2

なぜThread.sleepが機能するのかを調べる必要があると思います。コード自体が追加のスレッドを生成しているようには聞こえませんが、COM +コンポーネントを含めてコードベース全体を調べる必要があります。

まず最初に、デバッグでプログラムを起動し、F10キーを押してプログラムに入ります。次に、スレッドのデバッグウィンドウを開いて、あなたの質問に与えられているのと同数のスレッドがあるかどうかを確認します。そうした場合、それらは単にスレッドプールのスレッドに過ぎず、問題はおそらく複数のスレッドとは無関係です。

同じ数のスレッドが表示されない場合は、プログラムのさまざまな段階でブレークポイントを設定し、それらのスレッドがどこに作成されているかを確認してください。作成場所を見つけたら、その時点でいくつかのロックを追加することができます。しかし、あなたの問題は、複数のスレッドがメモリを破壊することによって引き続き発生する可能性があります。問題が複数のスレッドなどに起因すると確信できるまで調査してください。

問題が1つ以上のCOM +コンポーネントに関連している可能性があります。または、コードが長い実行中のデータベースストアドプロシージャを呼び出している可能性があります。いずれにせよ、Thread.sleepが動作する理由は、疑わしいコンポーネントが次の操作を開始する前に操作を完了するのに十分な時間を与えているからです。何の相互作用の問題は存在しない - この理論が真である場合に

は、それは操作とのThread.sleepを完了するために、操作を可能にするために十分に大きな値を与えたときの間に何らかの相互作用があることを示唆しています。これは、おそらくCOM +コンポーネントの1つが非同期的にいくつかのことを行っていることを示唆しています。ソリューションは、COM +コンポーネントのコード内でロックまたはクリティカルセクションを使用することです。もう一つのアイデアは、問題の原因となっているコードのセクションを複数の操作を同時に行うように再設計することです。

あなたが見ているC#コードの複数のスレッドが原因ではない可能性がありますが、起動前に完了するのに十分な時間が与えられないと失敗することがあります次の操作。これは、C#コード内の複数のスレッドが原因である場合とない場合があります。

+0

あなたは、これは私がやろうとしていることの一つです。アプリケーションは巨大で簡潔ではないので、明らかにこれは長い時間がかかります。 – AngelicCore