

#### 追記

多数のご意見ありがとうございます。編集しました。  
利用デバイスについての詳細は避けさせて頂きたいのですが、可能な限りで情報を記載しました。

### 前提条件

Windows10環境、言語はC# で、.NetFramework4.6.2
を用いて、あるデバイスのデータを取得してユーザーに提供するdllを作成しています。

あるデバイスは、WindowsPCとは独立したデバイスで、自身のクロックでデータを取得していき、そのデバイスの中にデータを蓄えていきます。そのバッファはFIFOのような形で、そのデバイスのドライバが提供するAPIを用いてデータを取得可能です。

### デバイス仕様/利用イメージ

①PCI、USB等がありますが、APIは同じです。  
②データ取得開始のAPIを叩くと、データ収集が開始されます。  
③データ収集が開始され、「一定数以上のデータが溜まるとイベントが発生」し、そのイベントの中で、データ回収処理を行います。（イベント発生データ数は初期処理で別途設定）  
④デバイスの中のバッファに再びデータが溜まり、イベントが起きて、データ回収してと繰り返します。

### 相談事項

相談したいのは、そのデバイスからデータを取得する処理でして、基本的に以下のような処理になりまして、定期的に実行されるイメージです。

① デバイス内のデータが一定数溜まるとイベントが発生  
② デバイス内データ数を取得するAPIを実行し、溜まっているデータ数を確認  
APIイメージ：GetDataCount（out DataCount）;  
③ ②で確認したデータ数分のInt32配列を確保  
④ デバイス内データを取得するAPIを実行し、②で確認したデータ数を指定して、③で確保した配列にデータを取得  
APIイメージ：GetData（DataCount, out DataArray[DataCount]）  
⑤ ④で取得したデータを別の配列に連携

上記で上手くいくと思っていたのですが、他の処理(別スレッドで画面にデータを表示する処理など)が重なったりすると、①でデータ数を確認してから、③でデータを取得するまでに遅延が発生し、デバイス側のバッファに予想以上のデータが溜まってしまう現象が起きます。

上記は、デバイスが「データが一定数溜まったら」イベントを発生させるという仕様でデータ回収する都合上で問題があります。

具体的には、以下のイメージです。（前提として、1000個でイベント発生とします。）

  1. デバイスでイベント発生：この時点で1000個溜まっている
  2. デバイスのデータ数を確認：1100個等のデータを確認（イベント発生後もデータ収集自体は続いているので）
  3. 1100個分の配列を確保
  4. デバイスから、1100個分のデータを取得  
→この時、デバイス内データが1000個以下なら、暫くして再度データ収集可能ですが、仮に2～4の間でデータ回収に時間がかかると、4の処理が完了した後にデバイス内のデータ数が1000個以上あると、次のイベントが発生せず、データ収集処理が走らなくなり、オーバーフローエラーが発生します。

出来れば、①から③の処理が終わるまで、他の処理が割り込むのを禁止するような処理があれば良いと思っております。

調べていると、Threadを利用して、①～③を優先度：Highestで実行するなどがありそうなのですが、もしも他に良さそうな処理があればご助言を頂くことは可能でしょうか。

上記はデバイスメーカーに相談したのですが、データ回収処理の優先度を上げる（質問事項です。）か、定期的にデータ数を確認してデータを回収してほしいと回答を受けました。

ただ、定期的にデータ数を確認する場合、アプリ側で常にデータ数を確認する必要があり、出来ればデバイスから発生するイベントで回収したいと考えておりました。


CC BY-SA 4.0
2023-04-13T13:20:24.427
94508
2023-09-24T07:51:59.220
2023-04-18T01:03:15.763
3060
57915
question
c# windows .net
C#において、ある処理の間は他の処理を割り込ませないようにする方法について、アドバイスいただけないでしょうか


対策を行う前に原因を特定することをお勧めします。そうでないと無関係で効果のない対策になりかねないです。

「①でデータ数を確認してから、③でデータを取得するまでに遅延が発生し」は考えられる原因候補ではありますが、単なる推測ではないでしょうか？
[Stopwatchクラス](https://learn.microsoft.com/ja-
jp/dotnet/api/system.diagnostics.stopwatch?view=netframework-4.6.2)などで所要時間を測定して原因かどうかを明確にしてください。

「デバイス側のバッファに予想以上のデータが溜まってしまう」は観測された事実かのように記述されていますが、実際のところはどうでしょうか？
③の前または後に再度溜まっているデータ数を確認されましたでしょうか？
そうではなくこれすらも推測ですと質問文には何の情報もなく、全く別のところに原因が存在する可能性も考えられます。

また想定される具体的なデータ量も提示してください。10Gbps NICで1GB/sのデータ処理が必要とかそういう状況なのでしょうか？
あてずっぽうですが、今どきのコンピューターであれば1MB/s程度なら、プログラムを適当に組んでも取りこぼすことはないような気がします…。

* * *

>
> この時、デバイス内データが１０００個以下なら、暫くして再度データ収集可能ですが、仮に２～４の間でデータ回収に時間がかかると、４の処理が完了した後にデバイス内のデータ数が１０００個以上あると、次のイベントが発生せず、データ収集処理が走らなくなり、オーバーフローエラーが発生します。

当初の質問には「イベント」という記載はありませんでした。「イベント」の発生条件の厳密な仕様を把握できていないことが原因ではありませんか？
つまり極稀にイベントの発生条件を満たしておらず待ちぼうけになっている可能性が考えられます。「エージング等で24時間以上回していると、データが回収されない現象が発生」も発生条件を満たす確率が低いだけで、条件を満たせば100%発生するのではと思います。

例えば1バイトでもデータが残っていたらイベントが発生しないという仕様の場合、スレッドのプライオリティをどんなに上げても「②データ数を確認」～「④データを取得」をゼロにすることはできません。仮にそのような仕様の場合は「④データを取得」の後に再度「データ数を確認」を行い、バッファが空になるまで繰り返す必要があります。

もしくは「データを取得」の仕様として大きめのバッファを渡した場合に読めるだけ読んで返してくれるのであれば、「④データを取得」で大きめのバッファを渡すことでも改善します。PCの搭載メモリに対してデータサイズが十分に小さいのであれば、「②データ数を確認」の２倍を確保するとか、「②データ数を確認」を実行せずに1MB決め打ちで確保するとか。それらも既に述べたようにデータ量を把握したり、各処理の所要時間を把握すれば、どのように設計すればいいかは見えてくるはずです。

> 定期的にデータ数を確認する場合、アプリ側で常にデータ数を確認する必要があり、出来ればデバイスから発生するイベントで回収したいと考えておりました。

「イベント」に対して行う処理（イベントハンドラ）をアプリ側で定期的に発報するタイマーからも呼び出せばいいのでは？
ただし根本的な解決とはならないのでお勧めはしません。

* * *

kunifさんの回答でC++言語が提案されている件について

質問文には「他の処理(別スレッドで画面にデータを表示する処理など)が重なったりすると」とあります。基本的にスレッド間は独立していて別スレッドの処理が重くなっても影響は受けません。もちろん影響を与える高負荷も存在しますが、その場合はC++言語での実装に切り替えても同様に影響を受けます。そのため、本件に関して
C# を他の言語に変更しても問題解決にはつながらないと考えられます。


CC BY-SA 4.0
2023-04-13T22:18:53.643
94513
2023-04-19T19:12:11.900
2023-04-19T19:12:11.900
4236
4236
94508
answer


そもそも、

> ② デバイス内データ数を取得するAPIを実行し、溜まっているデータ数を確認  
>  APIイメージ：GetDataCount（out DataCount）;  
>  ③ ②で確認したデータ数分のInt32配列を確保  
>  ④ デバイス内データを取得するAPIを実行し、②で確認したデータ数を指定して、③で確保した配列にデータを取得

がきちんとできているのであれば、②と④の間にどれだけ時間が経とうが、どれだけイベントが発生しようがエラーなどは起こりえません。

ピント外れな対策に頭を悩ませる前に、きちんとそのエラーの原因を突き止めましょう

追記  
処理中にデータが溜まってしまうとまずいってことだと思われますが、それははたしてWindows側で処理を止めればデータが溜まることはなくなるんでしょうか？

相変わらずピント外れな解決法なように思われますが。

そもそもその設計そのものから見直さないとダメな気がします


CC BY-SA 4.0
2023-04-19T00:07:01.610
94568
2023-04-20T11:12:53.117
2023-04-20T11:12:53.117
27481
27481
94508
answer