- PR -

ASP.NET上でのシリアル通信の実現について

1
投稿者投稿内容
yuta
会議室デビュー日: 2005/11/16
投稿数: 13
お住まい・勤務地: 愛知県→静岡県(転勤)
投稿日時: 2005-12-16 13:48
いつも参考にさせて頂いております、yutaです。

【目的】
 .NET対応の市販のRS-232Cシリアルコンポーネントを用いて、定周期
 毎にサーバーマシンに接続されたシリアルポートからデータを取得。

【手順】
 @コンポーネントをGlobal.asaxのWebフォーム上に張りつける
 AGlobal.asaxのApplication_Start()とApplication_End()にそれぞれ
  COMポートのオープンとクローズ処理を行う
 BTimerコンポーネントもGlobal.asaxのWebフォーム上に張りつけて、
  定周期イベントを実装し、中にシリアルからデータ取得処理を記述

【問題】
 @タイマー定周期イベントElapsed()を1000msecで設定してあるにも関わ
  らず、デバッグを繰り返しているとどういうわけか300msec位で呼ばれ
  てしまう。
 Aデバッグ用に定周期で呼ばれた際に、DebugWrite()で出力ウィンドウに
  メッセージを表示させています。(仮にこのプロジェクトをAとします)
  .NET 2003を新たに起動し、別のWebアプリを新規作成して実行させると、
  Aは全く実行させてないにも関わらず、どういうわけかAを実行させた時
  のデバッグメッセージがBの出力ウィンドウに表示されてしまう。
  (終了時、もしくはデバッグ停止時にApplication_End()の処理がちゃん
  と走っていないせい?)

 Aに関してはWebアプリを製作/デバッグするにあたって何か初歩的な過ち
  を犯しているような気がしますが、何卒お力添えの程お願いします。
  (開発環境:C# + ASP.NET[.NET 2003])
todo
ぬし
会議室デビュー日: 2003/07/23
投稿数: 682
投稿日時: 2005-12-16 14:22
ASP.NETには定周期な処理は不向きです。
Windowsサービスなどでやるのがいいでしょう。 
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2005-12-17 06:42
 ASP.NET は、クライアントからのアクセスが一定時間なかったり、確保したメモリが一定以上になると、アプリケーションを再起動します。

 このため、長時間にわたって裏で動作し続けるような処理には向いていません。
___________________________________________________________________
□ written by Jitta on 2005/12/17
□ Microsoft MVP :Visual Developer ASP/ASP.NET Oct.2005-Sept.2006
_________________
unibon
ぬし
会議室デビュー日: 2002/08/22
投稿数: 1532
お住まい・勤務地: 美人谷        良回答(20pt)
投稿日時: 2005-12-17 11:40
#引用時に丸囲みの数字は削りました。

引用:

yutaさんの書き込み (2005-12-16 13:48) より:
  デバッグ用に定周期で呼ばれた際に、DebugWrite()で出力ウィンドウに
  メッセージを表示させています。(仮にこのプロジェクトをAとします)
  .NET 2003を新たに起動し、別のWebアプリを新規作成して実行させると、
  Aは全く実行させてないにも関わらず、どういうわけかAを実行させた時
  のデバッグメッセージがBの出力ウィンドウに表示されてしまう。
  (終了時、もしくはデバッグ停止時にApplication_End()の処理がちゃん
  と走っていないせい?)


デバッガーを止めても、ASP.NET からデバッガーをデタッチ(接続の切り離し)するだけなので、ASP.NET のプログラムは裏で動きっぱなしのはずです。すなわち、Application_End は呼ばれていないと思います。
完全に止めるには、IIS のサービスを再起動するなどの方法があります。一例ですが iisreset のようなコマンドを使うと簡単です。とりあえずは OS を再起動とかでも良いわけですが。

引用:

yutaさんの書き込み (2005-12-16 13:48) より:
  タイマー定周期イベントElapsed()を1000msecで設定してあるにも関わ
  らず、デバッグを繰り返しているとどういうわけか300msec位で呼ばれ
  てしまう。


これは良く分からないのですが、たとえば、3つのタイマーのインスタンスが多重に動いているといったことはないですかね?だからイベントが3倍の頻度で発生しているとか?的外れかもしれませんが。
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2005-12-17 22:31
 あ、Timer って、3つあるんですよ。
System.Windows.Forms.Timer
System.Threading.Timer
あれ?もう1個なんだっけ?で、Forms.Timer は、Windows Forms でないと動作しない、残る2つのどちらかは、バグで Windows Service では動作しません。
で、Windows 2003 Server SP1 以外の環境では、Timer クラスにバグがあるので、HotFix を入手してください。
http://blogs.wankuma.com/jitta/articles/18668.aspx , http://blogs.wankuma.com/jitta/archive/2005/12/07/19848.aspx
yuta
会議室デビュー日: 2005/11/16
投稿数: 13
お住まい・勤務地: 愛知県→静岡県(転勤)
投稿日時: 2005-12-19 23:34
 yutaです。
 皆さん、素早いレスポンス有難うございます。
 あれから色々試したところ以下の事が分かりました。

【タイマーの飛んでくるタイミングがおかしい件】
 前準備として.NETから新規Webアプリを作成します。

 I)Global.asaxのWebフォームにTimerを張りつけた場合(1000msec間隔)
  Elapsed()イベントを次のように追加→1000msec間隔で1回ではなく2回
  出力ウィンドウに表示→×

 private void timer1_Tick(object sender, ・・・)
 {
   Debug.WriteLine("Output!");
 }

II)今度はWebForm1.aspxフォームにTimerを張りつけた場合(1000msec間隔)
  1000msec間隔で1回出力ウィンドウに表示→○

 以上の結果からどうやらGlobal.asaxにTimerを張りつけると上手く動かない
 みたいです。


【他のプロジェクトのデバッグメッセージが表示されてしまう件】
 コンピュータの[管理]から手動でIISのサービスを停止/起動させることで上
 手くデバッグできるようになりました!
 Application_End()は最後のユーザーがタイムアウトを起こした時にしか発生
 しないと思ってましたがそうじゃなかったんですね。
 定周期によるシリアル通信はやはりWebアプリでは無理という事なので皆さん
 に言われた通り(初の試みですが)Windowsサービスで作ってみようと思います。
1

スキルアップ/キャリアアップ(JOB@IT)