C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[4]: vScrollBar内で重たい処理をすると動作が変になります


(過去ログ 59 を表示中)

[トピック内 5 記事 (1 - 5 表示)]  << 0 >>

■33952 / inTopicNo.1)  vScrollBar内で重たい処理をすると動作が変になります
  
□投稿者/ 倉田 有大 (473回)-(2009/03/13(Fri) 21:28:31)

分類:[C#] 

2009/03/13(Fri) 21:46:34 編集(投稿者)
こんにちは倉田 有大です。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        ManualResetEvent m = new ManualResetEvent(false);

        public Form1()
        {
            InitializeComponent();
        }

        private void vScrollBar1_ValueChanged(object sender, EventArgs e)
        {
            m.Reset();
            ThreadPool.QueueUserWorkItem(waitCallback, "A");
            m.WaitOne();
        }
        private void waitCallback(object o)
        {
            Thread.Sleep(1000);
            m.Set();
        }
    }
}

こんなかんじで、vScrollBarのValueChangedイベントでManualResetEventでスレッドを止めて、スレッドプール内で時間がかかる処理をすると動作が変になります。
具体的に言うと、スクロールバー上でマウスをクリックしてスクロールバーの上にマウスを置いていると、マウスを放しても押しっぱなしのような状態になります。
回避方法がありましたなら、どなたかアドバイスお願いします〜

フリーソフトをマルチスレッド化したのですが、現在この不具合が〜この不具合が〜
バタンキューです。テルネリン飲んで休みます。

追記。すいません、ソースを実行する前にvscrollbar貼り付けて、ValueChangedイベントを割り当ててください。

引用返信 編集キー/
■33955 / inTopicNo.2)  Re[1]: vScrollBar内で重たい処理をすると動作が変になります
□投稿者/ ああ (1回)-(2009/03/13(Fri) 22:01:45)
No33952 (倉田 有大 さん) に返信
> こんなかんじで、vScrollBarのValueChangedイベントでManualResetEventでスレッドを止めて、スレッドプール内で時間がかかる処理をすると動作が変になります。
> 具体的に言うと、スクロールバー上でマウスをクリックしてスクロールバーの上にマウスを置いていると、マウスを放しても押しっぱなしのような状態になります。
> 回避方法がありましたなら、どなたかアドバイスお願いします〜
>
> フリーソフトをマルチスレッド化したのですが、現在この不具合が〜この不具合が〜
> バタンキューです。テルネリン飲んで休みます。
>
> 追記。すいません、ソースを実行する前にvscrollbar貼り付けて、ValueChangedイベントを割り当ててください。

EventHandler _event; int count = 0;
WaitCallback _callback;

public Form1()
{
InitializeComponent();
_event = new EventHandler(method);
_callback = new WaitCallback(waitCallback);
vScrollBar1.Minimum = 0; vScrollBar1.Maximum = 100;
vScrollBar1.SmallChange = 1; vScrollBar1.LargeChange = 1;
vScrollBar1.ValueChanged += new EventHandler(vScrollBar1_ValueChanged);
}

private void vScrollBar1_ValueChanged(object sender, EventArgs e)
{
vScrollBar1.ValueChanged -= new EventHandler(vScrollBar1_ValueChanged);
ThreadPool.QueueUserWorkItem(_callback, count);
}

private void waitCallback(object o)
{
Thread.Sleep(2000);
this.Invoke(_event);
}

private void method(object sender, System.EventArgs e)
{
this.Text = "count:" + (++count).ToString()
+ " Value:" + vScrollBar1.Value.ToString();
vScrollBar1.ValueChanged += new EventHandler(vScrollBar1_ValueChanged);
}
>
引用返信 編集キー/
■33957 / inTopicNo.3)  Re[2]: vScrollBar内で重たい処理をすると動作が変になります
□投稿者/ 倉田 有大 (474回)-(2009/03/13(Fri) 22:32:34)
ああ様、わかりやすいソースありがとうございます_(__)_さっそく試させてもらいました。

private void vScrollBar1_ValueChanged(object sender, EventArgs e)
{
vScrollBar1.ValueChanged -= new EventHandler(vScrollBar1_ValueChanged);
ThreadPool.QueueUserWorkItem(_callback, count);
}

private void waitCallback(object o)
{
Thread.Sleep(2000);
this.Invoke(_event);
}

これだと通常動作確認しました。
ただ、スレッドプールの後スレッドを止めていないため、スリープ中、他のコントロールとか押せてしまいますね。
スレッドが終わるまで、他の余計なコントロールのEnabledをfalseにしようかな?

引用返信 編集キー/
■33965 / inTopicNo.4)  Re[3]: vScrollBar内で重たい処理をすると動作が変になります
□投稿者/ 倉田 有大 (475回)-(2009/03/14(Sat) 13:03:04)
すいません、スレッドプールが動いている間、tabControlをロックする場合はどうすればよいのでしょうか?
tabCnotrol.Enabled == false;
にすれば、tabcontrol内にvscrollBarがあるため、また、vscrollBarが変になってしまいます。
スレッドが終わるまで、tabControlのメッセージを無視することは可能ですか?
引用返信 編集キー/
■33966 / inTopicNo.5)  Re[4]: vScrollBar内で重たい処理をすると動作が変になります
□投稿者/ 倉田 有大 (476回)-(2009/03/14(Sat) 13:29:06)
できたあああああああああああああああT^T

public class CustomTabControl : TabControl
    {
        public bool MouseLBUTTONEnabled = true;
        private const int WM_LBUTTONDOWN = 0x0201;
        protected override void WndProc(ref Message msg)
        {
            switch (msg.Msg)
            {
                case WM_LBUTTONDOWN:
                    {
                        if (MouseLBUTTONEnabled == false)
                        {

                            return;
                        }
                        break;
                    }
            }
            base.WndProc(ref msg);
        }
    }

tabcontrolを拡張して、一時的にマウスイベントをキャンセルさせて回避しました。
あー、しんどーT^T


引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -