0

3 つの値とキーのペアを持つ辞書があるとします。

private void someMethod()
{
    Dictionary<string, int> d = new Dictionary<string, int>();
    d.Add("cat", 22);
    d.Add("dog", 14);
    d.Add("llama", 2);
    d.Add("iguana", 6);

    somesortoftimercode
}

private void DisplayText(string x, int y)
{
    label1.Text = x;
    int someValue= 3+y;
}

このディクショナリを反復処理したい、ディスパッチャータイマー (またはタイマー) が 3 秒ごとにディクショナリの値で displayText を呼び出すようにしたい。それ、どうやったら出来るの?

アップデート:

Thread.Sleep(XXX) を使用できません。スレッドをブロックできません。私はバックグラウンドで他のことを行っていますが、これをスピンアウトしてスレッドをあちこちに配置することはできません。

プラス: http://msmvps.com/blogs/peterrichie/archive/2007/04/26/thread-sleep-is-a-sign-of-a-poorly-designed-program.aspx

4

5 に答える 5

2
private Timer timer;

private void someMethod()
{
    var d = new Dictionary<string, int>
                {
                    {"cat", 22}, 
                    {"dog", 14}, 
                    {"llama", 2}, 
                    {"iguana", 6}
                };

    int index = 0;
    TimerCallback timerCallBack = state =>
                                        {
                                            DisplayText(d.ElementAt(index).Key, d.ElementAt(index).Value);
                                            if(++index == d.Count)
                                            {
                                                index = 0;
                                            }
                                        };
    timer = new Timer(timerCallBack, null, TimeSpan.Zero, TimeSpan.FromSeconds(3));
}

private void DisplayText(string x, int y)
{
    label1.Text = x;
    int someValue= 3+y;
}

辞書を一度だけ列挙する必要がある場合は、次のコードを使用できます。

new Task(() =>
    {
        d.All(kvp =>
        {
            DisplayText(kvp.Key, kvp.Value);
            Thread.Sleep(3000);
            return true;
        });
    }
).Start();
于 2011-10-27T20:03:00.433 に答える
1

次のようなフレームワークによって提供されるタイマーのいずれかを使用できます。

System.Threading.Timers.Timer

foreach間隔を任意に設定してから、Tickイベントで、コレクションを反復処理するループを呼び出します。あなたの例によると

foreach(var pair in d)
{ 
   DisplayText(pair.key, pair.value);
}
于 2011-10-27T19:51:42.177 に答える
0

これにより、正しい方向に進むはずです。Win Forms アプリケーションを作成していると仮定します。そうでない場合、これはうまくいきません。

    private System.Windows.Forms.Timer t = new System.Windows.Forms.Timer();
    private Dictionary<string, int> d = new Dictionary<string, int>()
    {
        {"cat", 22},
        {"dog", 14},
        {"llama", 2},
        {"iguana", 6}
    };
    public Form1()
    {
        InitializeComponent();
        t.Tick += new EventHandler(t_Tick);
        t.Start();
    }

    void t_Tick(object sender, EventArgs e)
    {
        t.Stop();
        foreach (var item in d)
        {
            label1.Text = item.Key;
            int someValue = 3 + item.Value;
        }
        t.Start();
    }
于 2011-10-27T20:30:13.053 に答える
0

という名前のラベルが付いたフォームを作成し、次のlabellコードを試してください。

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        someMethod();
    }

    Thread thread;
    private void someMethod()
    {
        Dictionary<string, int> d = new Dictionary<string, int>();
        d.Add("cat", 22);
        d.Add("dog", 14);
        d.Add("llama", 2);
        d.Add("iguana", 6);

        thread = new Thread(new ParameterizedThreadStart(Do));
        thread.Start(d);
    }

    delegate void _DisplayText(string x, int y);
    private void DisplayText(string x, int y)
    {
        if (this.InvokeRequired)
        {
            this.Invoke(new _DisplayText(DisplayText), x, y);
            return;
        }
        label1.Text = x;
        int someValue = 3 + y;
    }

    public void Do(object dic)
    {
        Dictionary<string, int> d = (Dictionary<string, int>)dic;
        while (true)
        {
            foreach (var item in d)
            {
                DisplayText(item.Key, item.Value);
                Thread.Sleep(3000);
            }
        }
    }
}
于 2011-10-27T20:12:46.900 に答える
0

Reactive Extensions (Rx) ( Microsoft Cloud チームから) には、必要なことを行うための非常に優れた方法があります。

Rx への参照を追加した後 (NuGet を介して実行できます)、これをsomeMethodメソッドにドロップするだけです。

Observable
    .Interval(TimeSpan.FromSeconds(3.0))
    .ObserveOnDispatcher()
    .Subscribe(x =>
    {
        d.ToArray() // Helps to prevent race conditions
            .ForEach(kvp => DisplayText(kvp.Key, kvp.Value));
    });

バックグラウンド スレッドで起動するタイマーを設定し、クロススレッドの問題を防ぐために、ディスパッチャー (つまり、UI スレッド) への呼び出しをマーシャリングします。

Windows フォームを使用している場合、.ObserveOnDispatcher().ObserveOn(label1)orになり、準備完了.ObserveOn(form)です。

スレッド、タイマー、またはバックグラウンド ワーカーを明示的に作成する必要はありません。

Rx のリンクは次のとおりです。

于 2011-10-27T23:48:47.920 に答える