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/peterritchie/archive/2007/04/26/thread-sleep-is-a-sign-of-a-poorly-design-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

将间隔设置为您想要的任何值,然后在 Tick 事件中调用一个foreach循环遍历您的集合。根据你的例子

foreach(var pair in d)
{ 
   DisplayText(pair.key, pair.value);
}
于 2011-10-27T19:51:42.177 回答
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 Team)有一种非常好的方式来做你想做的事。

添加对 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 回答
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 回答