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

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

新規登録して質問してみよう
ただいま回答率
85.50%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

マルチスレッド

マルチスレッドは、どのように機能がコンピュータによって実行したのかを、(一般的にはスレッドとして参照される)実行の複合的な共同作用するストリームへ区分することが出来ます。

.NET Framework

.NET Framework は、Microsoft Windowsのオペレーティングシステムのために開発されたソフトウェア開発環境/実行環境です。多くのプログラミング言語をサポートしています。

Q&A

解決済

3回答

9826閲覧

C#でネットワーク通信をマルチスレッドで行う方法

退会済みユーザー

退会済みユーザー

総合スコア0

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

マルチスレッド

マルチスレッドは、どのように機能がコンピュータによって実行したのかを、(一般的にはスレッドとして参照される)実行の複合的な共同作用するストリームへ区分することが出来ます。

.NET Framework

.NET Framework は、Microsoft Windowsのオペレーティングシステムのために開発されたソフトウェア開発環境/実行環境です。多くのプログラミング言語をサポートしています。

0グッド

0クリップ

投稿2018/09/10 17:53

最近C#でプログラムを作成している中でしばしば気がかりな事があります.
ネットワーク通信をC#で取り扱う際に,非同期でデータを受信するメソッドが多々ありますが,受信したデータを処理する最中に次のデータを受信した場合はどのようになるのでしょうか.なるべくロストをしない場合にはどのようにすべきなのでしょうか.

例として,UDPでの通信を考えたとき,ReceiveAsyncで受信をした際に,データの受信自体は非同期で行われると思います.しかし,連続でデータを受信・処理する事を考えると,データの受信頻度が上がってくると処理はサブスレッドの回してなるべくReceiveAsyncのメソッドに戻るまでを早くすべきかと思うのですが,サブスレッドの生成自体にもコストが掛かるかと思います.

TCPであれば,受信確認があるため問題は無いかと思いますが,UDPやWebSocketでは一般的にどのように取り扱われているのでしょうか?

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2018/09/10 22:09

マルチスレッドで処理する理由は、windows アプリなら UI 応答性の向上、ASP.NET のような Web アプリならスループットの向上のはずですが、その辺りは理解した上での質問でしょうか?
退会済みユーザー

退会済みユーザー

2018/09/11 06:01

そのあたりは理解した上で,それらを抽象化して考えると,マルチスレッドする処理する理由はメインスレッドを占有させたくない場合,もしくは,並列化による作業時間の短縮と理解しております.今回私が考えているのは,例えばUDPの通信により1対多の通信をしており,複数のクライアントから同時にデータが送信されてくるような,頻度が高い送信が行われているような状況です.頻度が高く処理時間が長くなればシングルスレッドで処理している場合にはデータの処理中に次に送信されたデータをロストしてしまうのではないかという疑問です.
退会済みユーザー

退会済みユーザー

2018/09/11 06:45

> 送信されたデータをロストしてしまう ← もし、何らかの問題でそういうことがあるとしても、マルチスレッド化でそれが防止できるのでしょうか? どういう理由・メカニズムで防止できるとお考えですか?
退会済みユーザー

退会済みユーザー

2018/09/11 06:51

受信を待ち受けていない間にデータが到着した場合にロストが発生するのではないかと思います.受信待ち受け→データ処理→受信待ち受け→データ処理→・・・・という流れとすると,データ処理の工程が長くなるほどロストしやすくなり,であればデータ処理の工程を別スレッドにデータを投げるだけとすると防止できるのではないかと考えている次第です.
退会済みユーザー

退会済みユーザー

2018/09/11 11:17 編集

> 受信を待ち受けていない間にデータが到着した場合にロストが発生するのではないかと思います ← もしホントに待ちでロスが発生しているとすると(そんなことはないと思ってますが)、マルチスレッドにすればスレッドの切り替えのオーバーヘッドが増えて(質問者さんの例で言うと、データ処理→受信待ち受けのスレッドの切り替え)、改善どころか改悪になると思うのですが。自信度 90% ぐらいはあります。残り 10% は質問者さんが具体的にどういうコードを書いているか分からないというところ。前にも書きましたが、(1) windows アプリなら UI 応答性の向上、(2) ASP.NET のような Web アプリならスループットの向上以外にマルチスレッドのメリットはない、それ以外のところを目的にマルチスレッド化するとスレッドの切り替えのオバーヘッドで改善どころか改悪になると思います。
退会済みユーザー

退会済みユーザー

2018/09/11 10:13

確かにスレッド切替のオーバーヘッドとの兼ね合いですね.処理の部分にどれぐらいの時間がかかってるか次第で取るべき手段が変わりそうです.あとはudpの実装次第でしたね.
退会済みユーザー

退会済みユーザー

2018/09/11 11:15

兼ね合いなんてことはなくて、スレッド切り替えのためのオーバーヘッドが発生することによるデメリットしかないです。
guest

回答3

0

上の質問への私のコメントに返事がないので、以下は外れたことを言ってるかもしれませんが・・・

表題の「C#でネットワーク通信をマルチスレッドで行う方法」を、例えば(あくまで例えばです)、もっと具体的に「WPF アプリで WCF サービスとの通信を非同期で行う方法」というような形で考えていいのであれば、質問者さんの懸念、

なるべくロストをしない場合にはどのようにすべきなのでしょうか.

は考慮する必要はなさそうに思うのですが?

コメントに書きましたように「マルチスレッドで処理する理由は、windows アプリなら UI 応答性の向上」です。

具体例は、自分のブログで恐縮ですが、以下の記事を見てください。

WCF サービスの非同期呼び出し
http://surferonwww.info/BlogEngine/post/2018/02/28/call-wcf-service-method-asynchronously.aspx

記事の画像の WPF アプリで、[同期呼び出し]ボタンをクリックすると WCF サービスから応答が返ってくるまでブロックされて操作できませんが、[非同期呼び出し]ボタンクリックなら操作可能です。もちろん[非同期呼び出し]でも応答は期待通り返ってきます。

質問者さんのケースでは WCF サービスでなく UdpClient のようですが、マルチスレッドにする意味は同じことだと思います。いかがですか?

投稿2018/09/11 01:46

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

退会済みユーザー

退会済みユーザー

2018/09/11 06:04

先ほどの質問に対し,回答をさせて頂きました.UdpClientについて考えておりますが,UIについては今回特に考えておりません.
guest

0

あなたが初心者という自覚があるなら、非同期の送受信関数は使うべきではないです。

まず、同期関数でそのネットワーク通信をさせるコードを組み、それが完成したら、そのコードを別スレッドで走るようにさせましょう。

投稿2018/09/10 22:15

y_waiwai

総合スコア87719

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

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

退会済みユーザー

退会済みユーザー

2018/09/11 06:06

自分が今までに書いてきた非同期の送受信は特に問題無く動作しております.現状の要求に対しては問題無く対応できておりますが,一般的にはどのように処理されているのかが知りたいというのが今回の質問の趣旨となります.
guest

0

ベストアンサー

Task使えばいいんでは。
スレッドプールを使うのでスレッド生成コストは、ほとほどに気にするだけでいい

たぶん、やってほしいことをやってくれているのは、
dataflow-task-parallel-library
https://docs.microsoft.com/ja-jp/dotnet/standard/parallel-programming/dataflow-task-parallel-library
パイプラインをつくると、並列処理もうまいことやれる。
アクターモデルで、キューに詰め込み、キューから処理をしていくことをやってくれる。

追記
https://ufcpp.net/study/csharp/AsyncVariation.html
やりたいことはこの最後の図のような仕組みですね。

追記2
https://qiita.com/skitoy4321/items/c19ca3dc7624a7049fd5
今時はChannelsを使うといいみたい。

投稿2018/09/10 18:56

編集2018/09/11 13:38
kiichi54321

総合スコア1984

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問