[.NET] Thread @IT
- 2007 4/12
- 投稿者 : flied_onion
http://www.atmarkit.co.jp/fdotnet/mthread/mthread03/mthread03_01.html
カテゴリー : 2007年 4月
http://www.atmarkit.co.jp/fdotnet/mthread/mthread03/mthread03_01.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
namespace DataSetUpdateTest { class Program { static void Main(string[] args) { string response; DataSet ds = new System.Data.DataSet(); DataRow dr; DataSet newDs; DataRow[] rowsInError; DataTable newDt; DataColumn newCol; int i; SqlConnection sc = new SqlConnection(); sc.ConnectionString = "Data Source=PD3GCOT\\SQLEXPRESS;User ID=sa;Password=sa;" + "Initial Catalog=mydb;"; SqlDataAdapter sda = new SqlDataAdapter("Select * from Table_1;",sc); SqlCommandBuilder cb = new SqlCommandBuilder(sda); sc.Open(); sda.MissingSchemaAction = MissingSchemaAction.AddWithKey; sda.Fill(ds, "Table_1"); /* ds.EnforceConstraints = true; ds.SchemaSerializationMode = SchemaSerializationMode.IncludeSchema; ds.WriteXmlSchema("c:\\file.xsd"); */ ds.Tables["Table_1"].Rows[0].Delete(); DataRow delRow; if (ds.HasChanges(DataRowState.Deleted)) { newDs = ds.GetChanges(DataRowState.Deleted); if (!newDs.HasErrors) { delRow = newDs.Tables["Table_1"].Rows[0]; dr = ds.Tables["Table_1"].Rows[0]; try { // the following line generates the exception Console.WriteLine(delRow[0]); } catch (Exception e) { Console.WriteLine("01:" + e.Message); } try { Console.WriteLine(delRow[0, DataRowVersion.Original]); } catch (Exception e) { Console.WriteLine("02:" + e.Message); } try { Console.WriteLine(dr[0, DataRowVersion.Original]); } catch (Exception e) { Console.WriteLine("03:" + e.Message); } // dr.AcceptChanges(); //sda.Update(ds,"Table_1"); } else { Console.WriteLine("newDS has Error"); } } else { Console.WriteLine("newDS has no changes"); } if (sc.State == ConnectionState.Open) sc.Close(); sc = null; Console.WriteLine("Update was processed successfulle?"); Console.ReadLine(); } } } |
デバッグのステップインでたまにソースファイルを求められる場合があります。
俺の予想では、デバッグビルドだがpdbファイルがないdll(つーかアセンブリ)の場合に出現。
キャンセルするとそれ以降聞かれなくなりますが、その場合は以下のダイアログボックスで
「以下のソース ファイルを探さない」にソース名がいるやも。
— MSDN
[デバッグ ソース ファイル]
([ソリューション プロパティ ページ] ダイアログ ボックス – [共通プロパティ])参照
デバッグの設定と準備
このプロパティ ページでは、ソリューションのデバッグ時にデバッガによってソース ファイルが検索される場所を指定します。
[デバッグ ソース ファイル] プロパティ ページを開くには、ソリューション エクスプローラでソリューションを右クリックし、ショートカット メニューの [プロパティ] をクリックします。[共通プロパティ] フォルダを展開し、[デバッグ ソース ファイル] ページをクリックします。
[以下のパスからソース ファイルを検索する]
ソリューションのデバッグ時に、デバッガによってソース ファイルが検索されるディレクトリの一覧が表示されます。
[以下のソース ファイルを探さない]
デバッガによる読み取りから除外するファイルの名前を入力できます。デバッガは、上で指定したディレクトリのいずれかでこれらのファイルを見つけた場合、それを無視します。
参照
—–
ms-help://MS.MSDNQTR.2005JAN.1041/vsdebug/html/vxurfDebugSourceFilesCommonPropertiesSolutionPropertyPagesDialogBox.htm
2005のみ?
http://www.jurapun.com/Tutorial/CSharp/Thread.shtml
.NET Frameworkでは、スレッドを使うときThreadクラスとThreadStartデリゲートを使います。ThreadStartデリゲートは、次のように定義されています。
[ComVisibleAttribute(true)] public delegate void ThreadStart();
Threadクラスのコンストラクタは、4つのバージョン(オーバーロード)がありますが、ThreadStartデリゲートを使うバージョンは、
Thread(ThreadStart)
と宣言されています。デリゲートとは、安全な関数ポインタみたいなものなので、ThreadStartにはスレッドとして動作させるメソッドを設定します。
(注意) ThreadStartデリゲートをインスタンス化せずに
Thread th = new Thread(Func);
のように関数名を指定してもかまいません(自動的にデリゲートに変換されます)。
ThreadStartデリゲートの作るには
バックグランドで動作するメソッドの名前を引数としてThreadStartをインスタンス化する。
例 new ThreadStart(DoWork);
バックグランドで動作するメソッドのプロトタイプは、戻り値なし(void型)、引数なしであること。
例 void DoWork();
スレッドを使う手順
ThreadStartデリゲートを引数として、Threadクラスをインスタンス化する。
ThreadクラスのStartメソッドを呼び出す。
結局、次のようなコードを実行するとスレッドが走ります。
Thread thread = new Thread(new ThreadStart(Work));
…………
…………
void Work()
{
….
}
サンプル1
単純なサンプルです。スレッド関数を単に走らせるだけです。
ThreadStartデリゲートの問題点
ThreadStartデリゲートの関数プトロタイプは、
void Function();
という形式なので、パラメータを渡すことができません。これは実用上不便なので普通は、クラスを用意しそのコンストラクタのパラメータとしてスレッドのパラメータを渡します。そして、そのパラメータをThreadStartデリゲートで指定したメソッド(関数)が使用して処理を行うようにします。
サンプル2
スレッド用クラスを用意して、そのメンバ関数をスレッドとして走らせるサンプル
簡単にスレッドを使うためのクラス
スレッドを使うたびに、クラスを作って同じような処理を行うためのコードを書くのは面倒なので、Java風のRunnableという抽象クラスを作って、それをベースとしてスレッド用クラスを作ると便利です。サンプル3は、Runnableクラスとその使用例です。
サンプル3 (Runnable.cs, ThreadTest3.cs)
スレッドを便利に使うためのRunnableクラスを使ったサンプル
ParameterizedThreadStartデリゲートを使う
ParameterizedThreadStartデリゲートは、オブジェクトを引数とする関数を設定できます。ということは、データを直接にスレッドに渡すことができます。
ParameterizedThreadStartデリゲートを使うときの要件
スレッド関数は、void型でパラメータはobject型1個であること。
スレッドの開始は、Threadクラスのvoid Start(object)メソッドを使うこと。このメソッドの引数として、パラメータをスレッド関数に引き渡すことができる。
なお、このデリゲートは.NET Framework 2.0以上で使用できます。
サンプル4
ParameterizedThreadStartデリゲートを利用して、スレッドに直接データを渡して動作させる例。
スレッドの終了を待つには
サンプル1~4までは、スレッドの終了を待たずにMainが終了していました。これでは、すけっどの実行結果の表示やエラーがあったときの処理ができません。スレッドが終わるまで待つには、ThreadクラスのIsAliveプロパティを監視します。監視ループの中では、ThreadクラスのSleepメソッドを使って、メインスレッドをある時間間隔でスリープさせながら監視します。そうしないと、CPUの負荷が高くなって動作が重くなります。
(参考) Joinメソッドを使う方法(下記)も考慮してください。
サンプル5
サンプル4でスレッドの終了を待つようにしたサンプル。
呼び出しもとのスレッドをブロックするには
呼び出しもとで、スレッドの監視をすると無駄なCPUタイムを消費するし、コードも書かなくてはなりません。と言う訳で、Joinメソッドというものが用意されています。これを使うと、サンプル5はサンプル6のように書き換えできます。
サンプル6
サンプル5でjoinメソッドを使ってスレッドの終了を待つようにしたサンプル。
スレッドどうしの競合を回避するには
複数のスレッドが競合するリソースを使うときには、競合を回避する必要があります。例えば、あるスレッドがあるデータを書き換えている最中に、別のスレッドがそのデータを読み出すと困ったことが起こるかもしれません。そのような場合には、そのリソースをロックして、他のスレッドがアクセスできないようにすることができます。
lockキーワードは、次のような感じで使います。
void DoWork() {
……
lock (object1) { // object1は他のスレッドと競合するオブジェクト
…… // 他のスレッドと競合するコード
}
サンプル7
2つのスレッド関数が1つのオブジェクトを使うサンプル。
(参考)
Monitorクラスを使ってスレッドの競合を回避することもできます。lockキーワードはMonitorクラスを使って実装されているそうです。
スレッドどうしで同期を取るには
あるスレッドから別のスレッドへイベントを通知して、複数のスレッドが協調しながらある動作をさせたいときがあります。そのような場合は、AutoResetEventクラスやManualResetEventクラスを使います。
これらのクラスを使うと、スレッドはシグナルを通じて相互に通信できます。AutoResetEventクラスとManualResetEventクラスの違いは、シグナル状態のリセットが自動で行われるのか、手動で行うかです。ManualResetEventは複数のスレッドにシグナルを送るとき使います。
AutoResetEventクラスの使い方
AutoResetEventクラスをインスタンス化する。AutoResetEventコンストラクタは、bool型パラメータで初期のシグナル状態を指定する。
(例) AutoEventReset event1 = new AutoEventReset(false); // 非シグナル状態で初期化
イベント待ち側のスレッドは、WaitOneメソッドを使って、シグナル待ちで待機する。このとき、そのスレッドはブロッキング状態になる。
イベント発信側のスレッドは、発信可能になったらSetメソッドを使ってイベントをシグナル状態にする。
WaitOneメソッドで待機していたスレッドがブロッキングが解除され処理が続行される。
サンプル8
あるスレッドをシグナル待ちにして、別のスレッドがシグナルを送るサンプル
(参考) プロセス間で同期を取るときは、Mutexクラスを使います。
Windowsフォームでのバックグランド処理
Windowsフォームでバックグランド処理をするには、BackgroundWorkerコントロールを使うと簡単です。バックグランド処理は、DoWorkイベントハンドラを追加しその中にバックグランド処理を記述します。バックグランド処理に開始は、RunWorkerAsyncメソッドで開始することができます。
バックグランド処理が終了すると、RunWorkerCompletedイベントが発生するのでその中で後処理を行うことができます。
APIをコールせずに時間がかかる処理を行う場合は、Application.DoEventsメソッドをループ内でコールして、Windowsメッセージポンプを動作させます。そうしないと、Windowsメッセージがリアルタイムで処理されないため、他の操作が阻害されます。
Windowsフォームでスレッドを停止させるには
ApplicationクラスのExit()やExitThread()メソッドを使います。
天文学的な数値を変換しないかぎりはなくてもよさそう。
やるならtypeof(string)で中間キャストするよりも、
typeof(byte[])のほうがいいんじゃないかとも思われる。
typeof(string)の場合、Oracle DATE型の場合に時刻が失われるという事象が発生。
http://otndnld.oracle.co.jp/document/products/oracle10g/101/doc_v6/win.101/B15519-01/featSafeType.htm
VB.NET用のサンプルソース
C#用に書き換えてください。
— App.Config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="Application Name" value="MyApplication" />
</appSettings>
</configuration>
— 読み取りアクセス
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
MessageBox.Show("Application Name = " & _
System.Configuration.ConfigurationSettings.AppSettings("Application Name"))
End Sub
— 書き込みボタン
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim asm As System.Reflection.Assembly = System.Reflection.Assembly.GetExecutingAssembly()
Dim appConfigPath As String
appConfigPath = System.IO.Path.GetDirectoryName(asm.Location) + "\Config.exe.config"
Dim doc As System.Xml.XmlDocument = New System.Xml.XmlDocument
doc.Load(appConfigPath)
Dim node As System.Xml.XmlNode = doc("configuration")("appSettings")
Dim n As System.Xml.XmlNode
For Each n In doc("configuration")("appSettings")
If n.Name = "add" Then
If n.Attributes.GetNamedItem("key").Value = "Application Name" Then
n.Attributes.GetNamedItem("value").Value = Me.Text
End If
End If
Next
Dim newNode As System.Xml.XmlElement = doc.CreateElement("add")
newNode.SetAttribute("key", "Form Size")
newNode.SetAttribute("value", Me.Width & "," & Me.Height)
node.AppendChild(newNode)
doc.Save(appConfigPath)
End Sub
How To Get Current ColumnHeader
/// <summary>
/// 現在表示されている DataGridTableStyle を確認するには、
/// System.Windows.Forms.DataGrid の DataSource プロパティと
/// DataMember プロパティを使用して、CurrencyManager を返します。
/// データ ソースに ITypedList インターフェイスが実装されている場合は、
/// GetListName メソッドを使用すると、現在のテーブルの MappingName を返すことができます。
/// 上記の例を次の C# コードに示します。
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void saveColumnNameClipboardButton_Click(object sender, System.EventArgs e)
{
CurrencyManager myCM = (CurrencyManager)
BindingContext[dataGrid1.DataSource, dataGrid1.DataMember];
IList myList = myCM.List;
ITypedList thisList = (ITypedList) myList;
MessageBox.Show(thisList.GetListName(null));
PropertyDescriptorCollection pdc = thisList.GetItemProperties(null);
string s = "";
foreach(PropertyDescriptor pd in pdc)
{
s +=pd.Name + " // ";
}
MessageBox.Show(s);
}
まずクラスライブラリなどを作成するときにXMLドキュメントも生成します。
参照設定するdllと同じ場所にxmlファイルも置いておく。
なお、コマンドラインコンパイルの場合は/doc:hogehoge.xml オプションを利用する。
ms-help://MS.VSCC/MS.MSDNVS.1041/cscomp/html/vcerrDocProcessDocumentationComments.htm
ms-help://MS.VSCC/MS.MSDNVS.1041/csref/html/vcwlkXMLDocumentationTutorial.htm
Application.ThreadException +=new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
VisualStudio Visual Studio RegularExpression 正規表現 検索 置換
{}はマッチ数の範囲ではなく、タグつき正規表現となる。
[A-Z]{4}
としたい場合は
[A-Z]^4
と記述する。
[A-Z]{4,5}などに変わる記述があるかどうかは不明
see also
http://msdn2.microsoft.com/ja-jp/library/2k3te2cs.aspx
http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=30513&forum=7&6
http://www.ailight.jp/blog/kazuk/articles/6287.aspx
http://www.atmarkit.co.jp/fdotnet/special/java2cs/java2cs_02.html
http://msdn2.microsoft.com/ja-jp/library/ms173178.aspx
http://msdn2.microsoft.com/ja-jp/library/kbbwt18a.aspx
DataAdapter によるバッチ更新の実行
以前のバージョンの ADO.NET では、DataSet に格納されている変更内容をデータベースに反映する場合、DataAdapter の Update メソッドを実行して、1 行ずつデータベースを更新していました。このメソッドは、指定された DataTable 内の行を反復処理すると、各 DataRow を調べ、行が変更されたことを確認します。行が変更されている場合、その行の RowState プロパティの値に基づいて、適切な UpdateCommand、InsertCommand、または DeleteCommand のいずれかを呼び出します。各行の更新では、データベースへのネットワーク ラウンドトリップが発生します。
ADO.NET 2.0 では、UpdateBatchSize プロパティが DataAdapter によって公開されます。UpdateBatchSize を正の整数値に設定すると、データベースの更新が指定されたサイズのバッチとして送信されます。たとえば、UpdateBatchSize を 10 に設定すると、10 個の個別のステートメントがグループ化され、単一のバッチとして送信されます。UpdateBatchSize を 0 に設定すると、DataAdapter は、サーバーが処理できる最大のバッチ サイズを使用します。1 に設定すると、バッチ更新が無効になり、1 行ずつ送信されます。
サイズの大きいバッチを実行すると、パフォーマンスが低下する可能性があります。そのため、アプリケーションを実装する前に、バッチの最適なサイズ設定をテストする必要があります。
UpdateBatchSize プロパティの使用
バッチ更新を有効にする場合、DataAdapter の UpdateCommand、InsertCommand および DeleteCommand の UpdatedRowSource プロパティ値を、None または OutputParameters に設定する必要があります。バッチ更新を実行する際、FirstReturnedRecord または Both のコマンドの UpdatedRowSource プロパティ値は、無効になります。
UpdateBatchSize プロパティを使用するプロシージャを次に示します。このプロシージャは、2 つの引数を取ります。1 つは、Production.ProductCategory テーブル内の ProductCategoryID フィールドおよび Name フィールドを表す列を持つ DataSet オブジェクトで、もう 1 つは、バッチ サイズ (バッチ ファイル内の行数) を表す整数です。このコードにより、新しい SqlDataAdapter オブジェクトが作成され、その UpdateCommand、InsertCommand プロパティおよび DeleteCommand プロパティが設定されます。このコードは、DataSet オブジェクトによって行が変更済みになっていることを前提としています。このオブジェクトは、UpdateBatchSize プロパティを設定し、更新を実行します。
{C#}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
public static void BatchUpdate(DataTable dataTable,Int32 batchSize) { // Assumes GetConnectionString() returns a valid connection string. string connectionString = GetConnectionString(); // Connect to the AdventureWorks database. using (SqlConnection connection = new SqlConnection(connectionString)) { // Create a SqlDataAdapter. SqlDataAdapter adapter = new SqlDataAdapter(); // Set the UPDATE command and parameters. adapter.UpdateCommand = new SqlCommand( "UPDATE Production.ProductCategory SET " + "Name=@Name WHERE ProductCategoryID=@ProdCatID;", connection); adapter.UpdateCommand.Parameters.Add("@Name", SqlDbType.NVarChar, 50, "Name"); adapter.UpdateCommand.Parameters.Add("@ProdCatID", SqlDbType.Int, 4, "ProductCategoryID"); adapter.UpdateCommand.UpdatedRowSource = UpdateRowSource.None; // Set the INSERT command and parameter. adapter.InsertCommand = new SqlCommand( "INSERT INTO Production.ProductCategory (Name) VALUES (@Name);", connection); adapter.InsertCommand.Parameters.Add("@Name", SqlDbType.NVarChar, 50, "Name"); adapter.InsertCommand.UpdatedRowSource = UpdateRowSource.None; // Set the DELETE command and parameter. adapter.DeleteCommand = new SqlCommand( "DELETE FROM Production.ProductCategory " + "WHERE ProductCategoryID=@ProdCatID;", connection); adapter.DeleteCommand.Parameters.Add("@ProdCatID", SqlDbType.Int, 4, "ProductCategoryID"); adapter.DeleteCommand.UpdatedRowSource = UpdateRowSource.None; // Set the batch size. adapter.UpdateBatchSize = batchSize; // Execute the update. adapter.Update(dataTable); } } |
Web.Configで
(<configuration><system.web>内)
<identity impersonate="true" userName="zzzzz" password="xxxxxx"/>
ただし、パスワードが設定してあるユーザーでのみ有効。
※ドメインユーザーの場合はドメイン属性とか domain/zzzzz とかいうユーザ名になるやも。
認証モードがwindowsである必要があると思う。(デフォルトはwindows)
→ <authentication mode="Windows" />
identityに関する一般的な説明
→ http://www.microsoft.com/japan/msdn/net/security/SecNetAP05.aspx
アプリケーションレベルで偽装
→ http://support.microsoft.com/default.aspx?scid=kb;ja;306158
HelloWorldも実行できない状態なのです。
例えば、ソースは、
package exec;
public class Exec {
public static void main(String[] args) {
System.out.println("Hello World");
}
}
です。
JARファイル名 exec.jar
MANIFEST.MFには Main-Class: exec.Execと記述されています。
java exec で実行すると、
Exception in thread “main” java.lang.NoClassDefFoundError: exec
javaw exec で実行すると
Could not find the main class. Program will exit
と出ます。
–>
——————————————————————————–
java exec
——————————————————————————–
java -jar exec.jar
eclipse3.1.2
ついてきたconfigとの差分
osgi.splashPath=platform:/base/plugins/org.objectweb.lomboz.product,platform:/base/plugins/org.eclipse.platform
eclipse.product=org.objectweb.lomboz.product.lomboz
osgi.bundles.defaultStartLevel=4
ただし、splashpathとproductはもともともあるので、これにするならコメント化する必要アリ
http://www.atmarkit.co.jp/fjava/rensai/jsp2_01/jsp2_01_2.html
window>preferences
General>Appearance>Colors and Fonts
から設定可能
Editors>Text Editorsの下のほうにあるリンクからも飛べる。
http://download.eclipse.org/tools/emf/scripts/downloads.php
RTからダウンロード
SQL Serverのセキュリティ構成から、
「データベースエンジン」→「ローカル接続およびリモート接続」をオンにする。
ユーザーDSN→設定したユーザーしかつかえない
システムDSN→他のユーザーも使用可能
たとえばsun.jdbc.odbc.JdbcOdbcDriverを使っていて
javaアプリケーションではつながるが、servletにするとつながらない場合なんかはあやしい。
select * from sysobjectsとかでもだめならより一層怪しい。
●JSPの呼び出し方の違い
JSDK 2.0 以前
HttpServiceResponse.callPage()
JSDK 2.1
RequestDispatcher rd = ServletContext.getRequestDispatcher("JSPname");
rd.forward(request, response);
http://www02.so-net.ne.jp/~kikuta/jdbcnote/jdbcnote.html
http://support.microsoft.com/?scid=kb;ja;313100
http://www.ki.rim.or.jp/~kuro/Java/JDBC/JDBC-01.html
http://www.ki.rim.or.jp/~kuro/Java/JDBC/JDBC-02.html
— my source
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
public class jdbctest
{
public static void main(String[] args){
try{
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
String strConn = "jdbc:odbc:Ods01";
java.sql.Connection Conn =
DriverManager.getConnection(strConn,"sa","sa");
java.sql.Statement st=Conn.createStatement();
java.sql.ResultSet rs = st.executeQuery("SELECT * from sysobjects;");
while(rs.next())
{
System.out.println(rs.getString(2));
}
rs.close();
st.close();
Conn.close();
}
catch(java.sql.SQLException ex)
{
System.out.println("SQL Exception :" + ex);
ex.printStackTrace();
}
catch(Exception e){
System.out.println("Error:" + e);
e.printStackTrace();
}
}
}
http://www.nihon-eng.co.jp/c-break/TechNote/java/JAVA_SVLT3.htm
あと、tomcat全般
http://www.nihon-eng.co.jp/c-break/TechNote/tomcat/TCAT41_MnFrm.htm
javaのランタイムをインストールしなおした場合にパスの変更するために
それ以外にもjreを先にインストールした後でjdkをインストール場合なんかにも
window>preferences>
java>installed jre
・いつものようにwindows認証のみになっていないかを確認する。
・ManagementStudioなどでパスワードポリシーが有効になっていないか確認。
有効な場合は2文字のパスワードは許されないのでパスワードは間違っていないか確認する。
・saはデフォルトではEngineにはアクセスできるがログオンはできない状態になっている。
ManagementStudioでログイン→saのプロパティ→状態
を確認する。
セキュリティの設定も確認する。
→SQL Serverのセキュリティ構成から、「データベースエンジン」→「ローカル接続およびリモート接続」をオンにします。
過去のメモを登録していくつもりがなかなか登録に手間取り古い情報ばかりになってしまっていますのでご利用の際はご注意を
最近のコメント