レンジで作るドーナッツメーカー

さっきWBS見てたら子供がほしがりそうなおもちゃを発見。
早速ポチッとしちゃいました。届いたら子供にドーナツ作ってもらおう!

マルチスレッド環境でlongを共有するときの注意 (C#編)

id:nowokayがおもしろいことしてたので、.NETで試してみることにしました。

以下コード

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Diagnostics;

namespace VolatileSample
{
    public class VolatileSample
    {
        static long lock_ = 0;
        public static void Main(string[] args)
        {
            new Thread(delegate()
            {
                for (; ; )
                {
                    long t;

                    t = lock_;
                    long high = t >> 32;
                    long low = t & 0xffffffffL;
                    if (high != low)
                    {
                        Console.WriteLine("おわた");
                        Process.GetCurrentProcess().Kill();
                    }
                }
            }).Start();

            Random r = new Random();
            for (; ; )
            {
                long a = r.Next();
                if (a < 0) a -= Int32.MinValue;
                long t = (a << 32) + a;
                lock_ = t;
            }
        }
    }
}

案の定、.NETでもすぐ終了します。
で、Javaだとvolatile指定すればOKなんだけど、C#の場合は、longにはvolatile指定ができないようなので、lockするようにしてみます。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Diagnostics;

namespace VolatileSample
{
    public class VolatileSample
    {
        static long lock_ = 0;
        static object lockObj = new object();
        public static void Main(string[] args)
        {
            new Thread(delegate()
            {
                for (; ; )
                {
                    long t;

                    lock (lockObj)
                    {
                        t = lock_;
                    }
                    long high = t >> 32;
                    long low = t & 0xffffffffL;
                    if (high != low)
                    {
                        Console.WriteLine("終了");
                        Process.GetCurrentProcess().Kill();
                    }
                }
            }).Start();

            Random r = new Random();
            for (; ; )
            {
                long a = r.Next();
                if (a < 0) a -= Int32.MinValue;
                long t = (a << 32) + a;

                lock (lockObj)
                {
                    lock_ = t;
                }
            }
        }
    }
}

これで終了しなくなりました。

事故った

会社に来る途中、原チャリと接触事故をしてしまった。(当方チャリ)
幸い、ノートPCは壊れてなかったので事故扱いにしなかったんだけど、後からいろんなところが痛い。
まぁ、ただの擦り傷なんで大丈夫でしょう。

ListBoxでデータを読み込んだ後にすぐアイテムを選択する方法

WPFでListBoxにデータを読み込ませた後にすぐアイテムを選択しようと思ったのだが、
今までの考え方からすると、ListBox.Items.Countが1以上でない場合にSelectedIndexを設定すると例外が発生してしまうと思っていた。
なので、以下のようなコードを書いていた。

var q = from .....
        select ...;

listBox.DataContext = q;

// 一番上を選択状態にする
if (listBox.Items.Count > 0)
{
    listBox.SelectedIndex = 0;
}

これだと場合によってはItems.Countが入っていないことがあって(特に画面ロード時)、アイテムが選択されないことがあった。

そこで、データの方が1件以上入っていればとりあえず、SelectedIndexを変えてみるようにした。

var q = from .....
        select ...;

listBox.DataContext = q;

// 一番上を選択状態にする
if (q.Count() > 0)
{
    listBox.SelectedIndex = 0;
}

こうすると、リストのアイテムが選択されるようになったのでとりあえず、この方法で開発を進める。