Silverlight 同期処理

Posted in Silverlight on 10月 16th, 2010 by Site Administrator

SilverlightではWebClient等を使用して、非同期で各種データの取得ができます。

なんとか同期でデータの取得ができないかと調べてみたのですが、結論としては無理っぽい。

下記サンプルはデータを非同期で作成して、作成完了を待って戻すメソッドgetStringを含むtestクラスです。

呼び出し元からすると、getStringは同期処理で動くはずです。

    class test
    {
        private BackgroundWorker worker = new BackgroundWorker();
        private AutoResetEvent are = new AutoResetEvent(false);
        private string data = "";
        public test()
        {
            worker.DoWork += new DoWorkEventHandler(worker_DoWork);
            worker.RunWorkerCompleted += new
            RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
        }

        public string getString()
        {
            data = "";
            worker.RunWorkerAsync();
            are.WaitOne();
            return data;
        }
        private void worker_DoWork(object sender, DoWorkEventArgs e)
        {
            System.Threading.Thread.Sleep(1000);
            return;
        }
        private void worker_RunWorkerCompleted(object sender,
        RunWorkerCompletedEventArgs e)
        {
            data = "complete";
            are.Set();
        }
    }

上記クラスの呼び出し元について、下記のように書いてみます。

	private void button_Click(object sender, RoutedEventArgs e)
	{
		MessageBox.Show(this.getData());
	}

	private string getData()
	{
		string returnStr = "";
		test objTest = new test();
		returnStr = objTest.getString();
		return returnStr;
	}

結論として、動きません。反応なしです。書き換えてみます。

	private string getData()
	{
		string returnStr = "";
		Thread newThread = new Thread(() =>
		{
			test objTest = new test();
			returnStr = objTest.getString();
		//Dispatcher.BeginInvoke(() => MessageBox.Show(returnStr));
		});
		newThread.Start();
		return returnStr;
	}

動きますが、メッセージが空白表示です。Dispatcher.BeginInvokeのコメントをはずすと、きちんと表示されます。

別スレッド内では正常に動いているようです。スレッド終了を待つように書き換えてみます。

	private string getData()
	{
		string returnStr = "";
		Thread newThread = new Thread(() =>
		{
			test objTest = new test();
			returnStr = objTest.getString();
		//                Dispatcher.BeginInvoke(() => MessageBox.Show(returnStr));
		});
		newThread.Start();
		newThread.Join();
		return returnStr;
	}

正常に別スレッドのデータを取得できました!

次に、WebRequestでデータを取得するように変更します。
test.getStringを書き換えます。

	public string getString()
	{
		data = "";
		var wait = new AutoResetEvent(false);
		WebResponse ret = null;
		WebRequest wr = WebRequest.Create(new Uri("http://localhost:49698"));
		wr.BeginGetResponse(gr =>
		{
			ret = wr.EndGetResponse(gr);
			wait.Set();
		}, null);
		wait.WaitOne();
		var sr = new StreamReader(ret.GetResponseStream(), Encoding.UTF8);
		data = sr.ReadToEnd();
		ret.Close();
		return data;
	}

反応がありません。
getDataのThread.Joinをコメントアウトしてみます。

	private string getData()
	{
		string returnStr = "";
		Thread newThread = new Thread(() =>
		{
			test objTest = new test();
			returnStr = objTest.getString();
		//                Dispatcher.BeginInvoke(() => MessageBox.Show(returnStr));
		});
		newThread.Start();
		//newThread.Join();
		return returnStr;
	}

動きますが、メッセージが空白表示です。Dispatcher.BeginInvokeのコメントをはずすと、きちんと表示されます。

調べてみると、WebRequestの非同期データ取得の完了イベントは、UIスレッドに通知されるようです。

なので、UIスレッドでJoinなどの停止処理をいれていると、そこでロックがかかってしまうみたいです。

reactive extensionsを使えばできそうでもあるので、今後調べてみます。

Silverlight Object生成時の初期化パラメータ

Posted in Silverlight on 10月 15th, 2010 by Site Administrator

initparamsパラメータに、「パラメータ名=値」の形式で、複数ある場合はカンマ区切りで値を渡す。

<param name=”initparams”

value=”param1=param1value,param2=param2value />

なお、値を使うときは下記のとおり

private void Application_Startup(object sender, StartupEventArgs e)
{
string param1 = e.InitParams[“param1”];
string param2 = e.InitParams[“param2”];

//値を使う処理を下記続ける

}

Silverlight Firefox上での表示

Posted in Silverlight on 9月 24th, 2010 by Site Administrator

SilverlightオブジェクトをHTMLページへ埋め込む際の話。

<object data="data:application/x-silverlight-2,"
 type="application/x-silverlight-2" width="100%" height="100%">
1.heightを100%指定した場合
・Firefoxでは見えない
・IE8、Chromeでは表示される。が、それぞれで高さの解釈が異なる。
ちなみにVisualStudio2010で作成すると、デフォルトはこうなってる。

<object data="data:application/x-silverlight-2,"
 type="application/x-silverlight-2" width="100%" height="200px">
2.heightをpx指定した場合、
・Firefox、IE8、Chromeそれぞれ指定どおり見える。

heightはきちんと指定すること。