Hatena::ブログ(Diary)

はむ日記

2009-02-18

スレッド間の同期取り

下記処理で引っかかり中。デッドロックが回避できない気がしてきた。

f:id:ham007:20090218231353j:image

右のメインフォーム起動時にワークスレッドを起動させ、メッセージを出してからスレッドをロック。
メインフォームのボタンクリック時のイベントで、ワークスレッドを再開させてからメインスレッドをロックする。
この状態でワークスレッドが"再開したよ"ってメッセージを書きに行こうとするが
メインスレッドがロックされているからデッドロックになってしまうと。。。。

ソース

public partial class MainForm : Form
{
    private MessageForm sub_form;
    private Thread thread;
    private AutoResetEvent evt_thread;
    private AutoResetEvent evt_event;

    public MainForm()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        sub_form = new MessageForm();
        sub_form.Show();

        evt_thread = new AutoResetEvent(false);
        evt_event = new AutoResetEvent(false);

        thread = new Thread(work_thread);
        thread.Start();
    }

    private void work_thread()
    {
        dispText("[Thread] Waiting For PushEvent... ");
        evt_thread.WaitOne();

        /*
         * ワーカースレッドが再開したけども、メインスレッドはロックされたまま。
         * この状態でdispText()を行うと、デッドロックになる。。。
         */
        dispText("[Thread] Restart");
        evt_event.Set();
    }

    private void dispText(String msg)
    {
        sub_form.Invoke((MethodInvoker)delegate
        {
            sub_form.dispText(msg);
        });
    }

    private void button1_Click(object sender, EventArgs e)
    {
        dispText("[Event] Button Pushed");

        /*
         * このイベントはメインスレッドに属している。
         * その状態でウェイト処理でスレッドをロックする。
         */
        evt_event.Reset();
        evt_thread.Set();
        evt_event.WaitOne();
    }
}

ham007ham007 2009/02/21 15:34 例が悪すぎだ。

症状としては
PrintDocumentを使った印字処理のプリントイベントでWaiteOneでスレッドをロックしてたので、PrintPreviewDialogを使用してプレビュー表示したときにメインスレッドでプリントイベントが走ってしまうと。

とりあえずの解決策として別スレッドでプレビュー表示させました。
だけど、気持ち悪い。。。。

//印字ボタン押下でプレビュー表示
private void button_click(...)
{
Thread thread = new Thread(new ThreadStart(preview_thread));
thread.Start();
}

private void preview_thread()
{
PrintPreviewDialog dialog = new PrintPreviewDialog();
...
dialog.ShowDialog();
}

Connection: close