質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
VB.NET

Microsoft Visual Basic .NETのことで、Microsoft Visual Basic(VB6)の後継。 .NET環境向けのプログラムを開発することができます。 現在のVB.NETでは、.NET Frameworkを利用して開発を行うことが可能です。

Q&A

解決済

1回答

3192閲覧

プロセス間通信とネットワークの通信する時に出るエラーの原因が分からない

e4djbmra

総合スコア1

VB.NET

Microsoft Visual Basic .NETのことで、Microsoft Visual Basic(VB6)の後継。 .NET環境向けのプログラムを開発することができます。 現在のVB.NETでは、.NET Frameworkを利用して開発を行うことが可能です。

0グッド

0クリップ

投稿2020/08/18 03:09

編集2020/08/18 07:57

前提・実現したいこと

VB.NETでネットワークの通信とプロセス間通信をしています。
クライアントからデータを送信して、サーバーで受信用プログラムが受信して、データを保管。印刷用プログラムが保管されたデータから印刷にいくようなプログラムを作成しています。

プログラム自体は作成できたのですが、受信用プログラムが別スレッドで動かさないと、「アプリケーションはブレイクモードになりました」みたいなメッセージがでてきて止まってしまいます。

動作はしているのですが、同じプログラムなのに、スレッドの実装の仕方で、動作がおかしくなる原因が分からず困っています。

(データを大量に受信して、データを保管、印刷用のプログラムを起動して、大量にデータ読み込むと、おきます。)

発生している問題・エラーメッセージ

アプリケーションはブレークモードになっています。

例外がスローされました。
マネージド デバッグ アシスタント 'ContextSwitchDeadlock' : 'CLR は、COM コンテキスト 0xe37288 から COM コンテキスト 0xe371d0 へ 60 秒で移行できませんでした。ターゲット コンテキストおよびアパートメントを所有するスレッドが、ポンプしない待機を行っているか、Windows のメッセージを表示しないで非常に長い実行操作を処理しているかのどちらかです。この状態は通常、パフォーマンスを低下させたり、アプリケーションが応答していない状態および増え続けるメモリ使用を導く可能性があります。この問題を回避するには、すべての Single Thread Apartment (STA) のスレッドが、CoWaitForMultipleHandles のようなポンプする待機プリミティブを使用するか、長い実行操作中に定期的にメッセージをポンプしなければなりません。'

該当のソースコード

データ受信用のプログラム

Sub Main() (省略) ・・・・・ Dim channel As New IpcServerChannel("Sample") ChannelServices.RegisterChannel(channel, True) RemotingServices.Marshal(RemoteObject, "Sample", GetType(PrintSpool.PrintSpool)) Dim isEndFlg As Boolean = False While (True) '接続待ち While Not listener.Pending If True = Console.KeyAvailable() Then isEndFlg = True Exit While End If End While If True = isEndFlg Then Exit While End If '問題なく動作する。 'Dim myThread As Thread = New Thread(New ThreadStart(AddressOf DoWorkXML)) 'myThread.Start() 'こっちはアプリケーションはブレイクモードになっていますとでて、メモリがどんどん増えていく。 DoWorkXML() 'こっちもアプリケーションはブレイクモードになっていますとでて、メモリがどんどん増えていく。 'Task.Run(Sub() ' DoWorkXML() ' End Sub) End While End Sub .... Friend Sub DoWorkXML() Dim obj As PrintSpool.XmlData = Nothing Try 'XmlSerializerオブジェクトを作成 Dim serializer As New System.Xml.Serialization.XmlSerializer(GetType(PrintSpool.XmlData)) Dim xmlSettings = New System.Xml.XmlReaderSettings() _ With { .CheckCharacters = False } Using client = listener.AcceptTcpClient() Console.WriteLine("Client connected completed") Using ns As NetworkStream = client.GetStream() ns.ReadTimeout = 10000 If ns.CanRead Then Using xmlReader As Xml.XmlReader = System.Xml.XmlReader.Create(ns, xmlSettings) RemoteObject.data = CType(serializer.Deserialize(xmlReader), PrintSpool.XmlData) End Using Else client.Close() ns.Close() End If ns.Close() ns.Dispose() End Using End Using Catch ex As Exception Console.WriteLine(ex.Message) Finally End Try End Sub 印刷用のプログラム Sub Main() Dim channel As New IpcClientChannel() ChannelServices.RegisterChannel(channel, True) Dim sp = TryCast(Activator.GetObject(GetType(PrintSpool.PrintSpool), "ipc://Sample/Sample"), PrintSpool.PrintSpool) While (True) If 0 < sp.Count Then Try Dim getData As PrintSpool.XmlData = sp.data Console.WriteLine("key=" & getData.key) Console.WriteLine("value=" & getData.value) For Each row In getData.dt.Rows For i As Integer = 0 To 1 Console.WriteLine("dt " & row(i)) Next Next getData = Nothing Catch ex As Exception Console.WriteLine("Received:fail") End Try End If 'Catch ex As Exception 'End Try End While End Sub

試したこと

同じDoWorkXMLをメインスレッドなどで起動して、動作確認しました。

メインスレッドはNG
task.runはNG

スレッドOK
スレッドプールOK
タイマーOK

Using ns As NetworkStream = client.GetStream()
を実行して、中身何もなしでも、同じような症状。

補足情報(FW/ツールのバージョンなど)

VS2017

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2020/08/18 07:42

ソースコードは、インデントが消えて読みづらくなるのでコードの挿入で記入してください。
e4djbmra

2020/08/18 08:00

ご指摘ありがとございます。 修正させていただきました。 よろしくお願いいたします。
guest

回答1

0

ベストアンサー

ContextSwitchDeadLockで検索したら何件か引っかかりましたが、デバッグで時間の掛かる処理を行うとその例外が発生する事があるようです。設定で無効に出来るかもしれません。
デバッグ実行中に「CLR は、COM コンテキスト 0x1af66748 から COM コンテキスト 0x1af66870 へ 60 秒で移行できませんでした」エラーが発生する

投稿2020/08/18 08:23

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

e4djbmra

2020/08/18 08:39

ご回答ありがとうございます。 質問の仕方が悪かったかもしれません。 ContextSwitchDeadLockのエラーを無効にしたいのではなくて、 Dim myThread As Thread = New Thread(New ThreadStart(AddressOf DoWorkXML)) myThread.Start() では、まったく問題がおきないのに、 メインスレッドやタスクを使うと、使用しているメモリが増えて(接続待機が増えている?) アプリケーションはブレークモードになっています。 というエラーが出てくることです。 うまく伝えられないのですが、同じプログラムで、スレッドの書き方で、エラーになったり、ならなかったりするのが、なぜなのか分からないのです。 (そもそも今行っているテストでは、長い処理はしないようにしているので、このエラーが出てくることはないと思っています。) よろしくお願いいたします。
退会済みユーザー

退会済みユーザー

2020/08/19 05:41 編集

http://bbs.wankuma.com/index.cgi?mode=al2&namber=70251&KLOG=120 同じような現象の事例を見つけましたが、VBコンソールアプリのメインスレッドはデフォルトでSTAThreadだから発生するのかも。Taskでも発生するのは、ちょっと理由が判らないですが… MTAThreadを指定したら、メインスレッドでも大丈夫かもしれません。 [contextSwitchDeadlock MDA] https://docs.microsoft.com/ja-jp/dotnet/framework/debug-trace-profile/contextswitchdeadlock-mda > Visual Basic コンソール アプリケーションでこの MDA がアクティブ化されるのを防ぐには、 > メイン メソッドに MTAThreadAttribute 属性を適用するか、 > またはメッセージをポンプするようにアプリケーションを変更します。 コンソールアプリでメッセージポンプしろというのも、ちょっと変な感じはしますね。
e4djbmra

2020/08/19 06:12

ご回答ありがとうございます。 フォームアプリで確認したところ問題はなくなっていました。 色々調べてくださり、ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問