2007年01月29日

AutorResetEventによる同期

   このエントリーをはてなブックマークに追加 Clip to Evernote
今まで、C#で、AutorResetEventを使ったコードを書いたことがなかったので、
動きを確かめるため、書いてみた。

using System.Threading;
...

private List<AutoResetEvent> areList = new List<AutoResetEvent>();

private void Run() {
for (int i = 0; i < 3; i++) {
AutoResetEvent are = new AutoResetEvent(false);
areList.Add(are);
Thread th = new Thread(Start);
th.Start(are);
}
AutoResetEvent.WaitAll(areList.ToArray());
Console.WriteLine("Thread End");
Console.ReadLine();
}

private Random rnd = new Random();
private void Start(object obj) {
Console.WriteLine("Thread Start");
Thread.Sleep(1000*rnd.Next(1,4));
Console.WriteLine("Thread Stop");
((AutoResetEvent)obj).Set();
}


このコードは、3つのスレッドを起動し、すべてが終わるまで待つというコード。
どれかひとつを待つのならば、WaitAny staticメソッドか、WaitOneメソッドを使えばよい。

WaitOneの場合は、AutoResetEvent のインスタンスはひとつだけでよいので、
コードも簡単だ。(コードは省略)

ManualResetEvent の場合は、Resetをするコードも必要なので、スレッドの終了待ちの
ようなコードは、AutoResetEventの方が楽ですね。  

Posted by gushwell at 21:14Comments(0)TrackBack(0)

2007年01月25日

独自のWMIの管理データクラスの強制再インストール

   このエントリーをはてなブックマークに追加 Clip to Evernote
C#で独自のWMIの管理データクラスを作成した場合、.NET Framework SDK に用意されている installutil.exe ユーティリティをつかってインストールをしますが、Main()関数の先頭に次のコードを追加することでも、インストールすることが可能です。
 string[] installArgs = new String[] {
"/logfile=",
"/LogToConsole=true",
"/ShowCallStack",
Assembly.GetExecutingAssembly().Location,
};
System.Configuration.Install.ManagedInstallerClass.InstallHelper(installArgs);

しかしながら、WMI Tester (wbemtest.exe) を使って、インストールしたクラスを削除してしまうと、上記コードで、再インストールすることができません。
これって、WMI Tester (wbemtest.exe) 側のバグじゃないかなと思うのですが、MSの見解では、規定の動作なんだそうです。

この場合は、

 installutil.exe /f  [yourassemblyname]

として、強制的に再インストールするか、

 string[] installArgs = new String[] {
"/f",
"/logfile=",
"/LogToConsole=true",
"/ShowCallStack",
Assembly.GetExecutingAssembly().Location,
}

のように、InstallHelper に渡すオプションに、/f を付加するかの、どちらかの方法で、再インストールすることができます。

後者の方は、installArgs で設定しているのが、installutil のコマンドラインオプションそのものなので、もしかして? と思って、/f をつけたら案の定うまくいきました。  
Posted by gushwell at 22:47Comments(0)TrackBack(0)

2007年01月17日

C#でWMI のデータ プロバイダ

   このエントリーをはてなブックマークに追加 Clip to Evernote
簡単な WMI のデータ プロバイダをC#で作成してみた。

完成してみれば、拍子抜けするほど簡単なコードなんだけど、キュメントがわかりにくいし、Webページを探しても、ほとんど、WMI のデータ プロバイダを作成するようなコードがなかったので、かなり手こずった。

結果的には、

http://msdn2.microsoft.com/ja-jp/library/ms257343(VS.80).aspx

に書いてあるコード、そのままでOKなんだけど、WMIそのものの理解が浅いため、このプロバイダを利用する側のコードが間違っていることに気がつかなかった。。。


でも、いろいろ悩んだだけあって、少しは理解が深まった。

wbemtest.exe なるツールの使い方もすこしわかったし。  
Posted by gushwell at 23:20Comments(0)TrackBack(0)

2007年01月16日

『Java言語で学ぶリファクタリング入門』

   このエントリーをはてなブックマークに追加 Clip to Evernote
結城浩さんの『Java言語で学ぶリファクタリング入門』がソフトバンク から1月下旬に、刊行されるようです。
『Java言語で学ぶデザインパターン入門』には、大変お世話になったので、この本にも期待しています。
  
Posted by gushwell at 21:25Comments(0)TrackBack(0)

2007年01月15日

Schtasksコマンド

   このエントリーをはてなブックマークに追加 Clip to Evernote
Schtasks
へーん、こんなコマンドがあったんだ。
ATコマンドしか知らなかった...

http://www.microsoft.com/technet/prodtechnol/windowsserver2003/ja/library/ServerHelp/1d284efa-9d11-46c2-a8ef-87b297c68d17.mspx?mfr=true


Webページから抜粋
Schtasks
定期的または特定の時間にコマンドおよびプログラムを実行するようスケジュールします。スケジュールのタスクの追加と削除、要求時のタスクの開始と停止、およびスケジュールされたタスクの表示と変更を行います。


/ru [Domain\]User /rp Password

上記オプションで、起動するユーザアカウントとパスワードを指定できます。  
Posted by gushwell at 23:11Comments(0)TrackBack(0)

2007年01月10日

2つのAppDomain間でのClassの共有は?

   このエントリーをはてなブックマークに追加 Clip to Evernote
2つのAppDomainを作成し、そこから、あるクラスの static メンバーを参照してみた。
例えば、こんなクラス。

public static class MyClass1 {
public static Random rnd = new Random();
public static int Num = rnd.Next();
}

このクラスを利用するコードは、面倒なので省略。
このクラスの num フィールドの値を、2つのAppDomainで出力してみると、別々の値を出力した。

なるほど。
コード上は、ひとつのインスタンスを参照するようなプログラムも書けてしまうので、気をつけないとバグを埋め込みそうだな。

  
Posted by gushwell at 22:23Comments(0)TrackBack(0)

2007年01月07日

AppDomain.DoCallBack メソッド

   このエントリーをはてなブックマークに追加 Clip to Evernote
AppDomain.DoCallBack メソッドを使うと、別のアプリケーションドメイン内のコードを実行させることができる。

public static void Main() {
Console.WriteLine(AppDomain.CurrentDomain.GetHashCode().ToString());

AppDomain domain = AppDomain.CreateDomain("DomainB",
null,
(AppDomainSetup)null);
ObjectHandle oh = domain.CreateInstance("GushwellAssembly", "Gushwell.MyType");

MyType testObj = (MyType)oh.Unwrap();
testObj.Execute(AppDomain.CurrentDomain, new CrossAppDomainDelegate(CallBackMethod));
}

public static void CallBackMethod() {
Console.WriteLine(AppDomain.CurrentDomain.GetHashCode().ToString());
}

----
namespace Gushwell {
public class MyType : MarshalByRefObject {
public void Execute(AppDomain domain, CrossAppDomainDelegate del) {
Console.WriteLine(AppDomain.CurrentDomain.GetHashCode().ToString());
domain.DoCallBack(del);
}
}
}


上記コードでは、DomainB から、デフォルトの AppDomainで動作するコード(CallBackMethod)を呼び出している。  
Posted by gushwell at 18:09Comments(0)TrackBack(0)

2007年01月06日

AppDomainでのデリゲート

   このエントリーをはてなブックマークに追加 Clip to Evernote
AppDomainの動作を調べるために、以下のようなコードを書いてみた。
別AppDoaminのメソッドを呼び出す際に、Delegateを引数に渡し、
呼び出されたAppDomainのメソッドから、そのDelegateを呼び出すというもの。

public static void Main() {
Console.WriteLine(AppDomain.CurrentDomain.GetHashCode().ToString());

AppDomain domain = AppDomain.CreateDomain("DomainB",
null,
(AppDomainSetup)null);
ObjectHandle oh = domain.CreateInstance("GushwellAssembly", "Gushwell.MyType");

MyType testObj = (MyType)oh.Unwrap();
testObj.Execute(CallBackMethod);
}

public static void CallBackMethod() {
Console.WriteLine(AppDomain.CurrentDomain.GetHashCode().ToString());
}


public delegate void AppDomainDelegate();

public class MyType : MarshalByRefObject {
public void Execute(AppDomainDelegate del) {
Console.WriteLine(AppDomain.CurrentDomain.GetHashCode().ToString());
del();
}
}


この場合、CallBaclMethodは、Main()が実行されているデフォルトのAppDomainではなく、作成した"DomainB"側で、処理が実行される。

...
で、MSDNのドキュメントを見ていたら、AppDomain.DoCallBack メソッドがあるのを知る。なるほど、これを使うと、delegateを別ドメインで動作させることもできるみたいだ。
  
Posted by gushwell at 17:18Comments(0)TrackBack(0)