- PR -

画面Load時のClose処理について。

投稿者投稿内容
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2006-09-11 17:56
引用:

いえ蔵さんの書き込み (2006-09-11 17:41) より:

〜Form Closed イベント処理〜
 1. データベースClose


それまで '開きっぱなし' なのですね。

引用:

なぜ、Form Load イベント処理でForm Close処理を行いたかったと
申しますと・・・
 (1) データベースOpen処理だけでなく、データベースOpen後(項番3.)の処理にて、
   システムエラーが発生した場合、必ずデータベースをCloseさせたい。


必ずという意味では、try ~ finally に委ねるべきことです。

引用:

(2) プログラムのいろいろな所に、データベースClose処理を記述せずに、
  1つのイベントのみに記述したい。
  これは、コーディングルールを分かりやすくしたかった為です。

皆様から返信頂いた内容で考えた結果・・・
〜 Sub Main 〜
 1. データベースOpen

〜Form Load イベント処理〜
 1. データベースよりFormに表示するデータをSelect
 2. 項番2.で取得したデータをFormに表示

〜Form Closed イベント処理〜
 1. データベースClose

Form Load時に発生したシステムエラー処理は、Form Load後、ユーザが押下した
終了ボタン等でデータベースをCloseさせるといった方法が良いと思いました。


それまで '開きっぱなし' なのですね。

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
masa
大ベテラン
会議室デビュー日: 2004/10/28
投稿数: 161
投稿日時: 2006-09-11 18:01
> 〜Form Closed イベント処理〜
> 1. データベースClose

Openと同レベルで Close したほうがよいような気もします。
他のフォームがメインフォームになったり、
複数のフォームを同時に開いて使用しなくなったら
それぞれ閉じるような仕様になったとしても、
修正の手間がかからない方法にしていくといいのではないでしょうか。


また、アプリケーションの開始・終了を制御するには、
ApplicationContext を使用する方法もあります。
コンテキストにDBインスタンスなど全体で使用するものを持たせ、
コンテキストの MainForm にメインフォームとして使用するフォームをセットします。
そして、

 Application.Run(context)

のように、Run の引数にコンテキストを渡します。

コンテキストを使うと、
メインフォームが閉じられたら終了、とか、
全てのフォームが閉じられたら終了、とか終了条件を決められますし、
アプリケーションの開始・終了処理をまとめるのにも便利です。

一つカスタマイズしたコンテキストを作っておくと、
いろいろなアプリケーションの開始・終了処理の動作を統一するのに役立つと思います。
いえ蔵
会議室デビュー日: 2006/02/16
投稿数: 4
投稿日時: 2006-09-11 18:14
お世話になっております。

何度も記述漏れで申し訳ありません(T_T)。

Form Load時から、Close迄の間に、データベースをCloseしないのは、
イベントの発生、SQL発行時等、常にデータベースにログを出力しています。
(ユーザがどんな動作を行ったのか、どんなデータを見たのかを、セイキュリティ上
判断する必要がある為です)

イベント発生毎にデータベースのOpen、Closeを行うのではなく、 From LoadからCloseまで
データベースの接続を保持する事によって、パフォーマンスの向上を考えたものなのですが・・・

一般的に、いけない行為なのでしょうか?
ぶさいくろう
ぬし
会議室デビュー日: 2005/11/22
投稿数: 1232
お住まい・勤務地: 川崎市(は俺も含めてロクな人間が住んでないよw)
投稿日時: 2006-09-11 18:47
引用:

いえ蔵さんの書き込み (2006-09-11 18:14) より:
一般的に、いけない行為なのでしょうか?


いけない行為だしパフォーマンスもそれほど改善しない。(ほんの少しだけだな)
コネクションプーリングって物もありますし。。。 という発言を見逃さないように。
うにくま
ベテラン
会議室デビュー日: 2005/11/05
投稿数: 82
投稿日時: 2006-09-11 19:08
引用:

イベント発生毎にデータベースのOpen、Closeを行うのではなく、 From LoadからCloseまで
データベースの接続を保持する事によって、パフォーマンスの向上を考えたものなのですが・・


ですが、殆どパフォーマンスには影響しません。
最上階に到着するまで60秒掛かるエレベータが59秒になる程度です。
そして、その1秒の為に乗り心地や安全性を捨るようなものです。
それよりは気持ち良く安全に到着するよう設計した方が良いと思います。

まずは読み易く安全に動くように設計/開発して、
それでパフォーマンスに問題が発生したら原因を調査してから対策を施したした方が良いですよ。
ダッチ
大ベテラン
会議室デビュー日: 2005/10/31
投稿数: 113
投稿日時: 2006-09-11 21:30
ダッチです。

引用:

いえ蔵さんの書き込み (2006-09-11 18:14) より:
イベント発生毎にデータベースのOpen、Closeを行うのではなく、 From LoadからCloseまで
データベースの接続を保持する事によって、パフォーマンスの向上を考えたものなのですが・・・


ぶさいくろうさん や うにくまさん も言っていますが、
クライアントから見れば、パフォーマンスはわずかに向上するかもしれません。

しかし、データベースがある端末(多分サーバ)からすると
ずっとコネクションが貼られているというのは負荷がかかります。
そのため、パフォーマンスは低下する可能性があります。

操作する端末から見えない端末(多分サーバ)にも
目を向けてみてはいかがでしょうか。
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2006-09-11 21:58
引用:

 2 プログラムのいろいろな所に、データベースClose処理を記述せずに、
   1つのイベントのみに記述したい。
   これは、コーディングルールを分かりやすくしたかった為です。


 フォームを開いている間中、コネクションを張りっぱなしと言うことは、そのフォームを表示できるのは、購入したライセンスの数まで、ということになります。
 この意味でも、必要なときだけ、開いてとじる。


 データベースとのやりとりを行う、専用のクラスを用意します。フォームとデータベースを分離しておけば、使い回しや保守の面で楽になります(設計は苦しくなる。。。)
この辺の設計は、経験依存するかも?
コード:
こいつは別のプロジェクトにする
class UserTableAdapter {
	private SqlConnection connection;
	public UserTableAdapter() {
		connection = new SqlConnection();
		その他必要な設定
	}
	public DataTable ReadData() {
		try {
			connection.Open();
			読む処理
		} finally {
			connection.Close();
		}
	}
}
_____

class Form1 {
	private UserTableAdapter userTable;
	↑コンストラクタで作っておく
	
	protected void 読みたいところ() {
		DataTable table = userTable.ReadData();
	}
}


※ あくまでコーディングの方向性を示すものであり、動くものではありません。
Jubei
ぬし
会議室デビュー日: 2002/03/02
投稿数: 830
お住まい・勤務地: 関西
投稿日時: 2006-09-12 01:05
諸農です。
お久しぶりです、objectさん。

ちょっと気になったのですが、

引用:

Formの「Loadイベント」は、
「Createイベント」
つまり、
「Formのコンストラクション処理中」
と考えるべきだと思います。

そして、これは、
「生成処理の真っ只中」
という、とても不安定に期間ですから
かなり記述に注意が必要です。
#この処理は、言語にもかなり依存しています。
#また、名前が
#「Loadイベント」
#なので誤解を招きやすいんでしょうね。



FormのLoadイベントはコンストラクタ処理が終了して、フォームが初めて表示される直前に呼び出されるのでは?
Form.Load イベント

で、このフォームが表示された時にユーザーカスタマイズとして必要とするリソースを割り当てておくイベントがForm_Loadって事ではないかと。デザイナで設定されている情報はコンストラクタから呼ばれるInitializeComponent()メソッド内で完了していますし。実際、次のようなコードも実行可能です。これはオブジェクトのコンストラクタが完了して、オブジェクトが生成済みだからですよね。もちろん、Form1 f = new Form1() から次のMessageBox.Show(f.MyFunction(10, 20).ToString())までの間に"Form_Loadが呼び出されました"と言うメッセージは表示されません。

コード:
private void Form1_Load(object sender, EventArgs e)
{
    MessageBox.Show("Form_Loadが呼び出されました");
}

private void button1_Click(object sender, EventArgs e)
{
    Form1 f = new Form1();
    MessageBox.Show(f.MyFunction(10, 20).ToString());
}

public int MyFunction(int x, int y)
{
    return x + y;   
}




ドキュメントにLoadイベント内でCloseは呼ばないでって書かれている意図は、ユーザカスタマイズで必要なリソース割り当ての最中に、割り当て対象が破棄されるとメモリリークが起きますよって事ではないでしょうか。でないと、ドキュメントの同じ箇所に書かれている「Form.Activated イベント」までコンストラクション中って意味になってしまうと思うんですけど(^^;


おそらくDelphi for Win32と同じだと勘違いされているのではと思います。
Delphiだとコンストラクタ呼び出し(またはAfterConstructionから)でFormCreate(TCustomForm.DoCreateの中でFOnCreate)が呼ばれますから。

コード:
procedure TForm1.Button1Click(Sender: TObject);
var
  f:TForm1;
begin
  f := TForm1.Create(self);
  ShowMessage(IntToStr(f.MyFunction(10,20)));
  f.Release;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  ShowMessage('FormCreate');
end;

function TForm1.MyFunction(X, Y: Integer): Integer;
begin
  Result := X + Y;
end;



_________________
諸農和岳
Powered by Turbo Delphi & Microsoft Visual Studio 2005

十兵衛@わんくま同盟
http://blogs.wankuma.com/jubei/

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