перечислять через список или диктовать каждые х секунд с таймером или диспетчером в C # - PullRequest
0 голосов
/ 27 октября 2011

говорят, что у меня есть словарь с 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;
}

Я хочу перебирать этот словарь, я хочу, чтобы диспетчер (или таймер) вызывал displayText со значениями словаря каждые 3 секунды.Как мне это сделать?

ОБНОВЛЕНИЕ:

Я не могу использовать Thread.Sleep (XXX), я не могу заблокировать поток.у меня есть другие вещи, идущие в фоновом режиме, и я не могу раскрутить это, чтобы повсюду были темы.

плюс: http://msmvps.com/blogs/peterritchie/archive/2007/04/26/thread-sleep-is-a-sign-of-a-poorly-designed-program.aspx

Ответы [ 5 ]

2 голосов
/ 28 октября 2011
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();
1 голос
/ 27 октября 2011

Вы можете использовать любой из таймеров, предоставляемых платформой, например,

System.Threading.Timers.Timer

Установите интервал на то, что вы хотите, а затем в событии Tick вызовите цикл foreach, который перебирает вашу коллекцию. По вашему примеру

foreach(var pair in d)
{ 
   DisplayText(pair.key, pair.value);
}
0 голосов
/ 28 октября 2011

У 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));
    });

Он устанавливает таймер - который запускается в фоновом потоке - и затем направляет вызов диспетчеру (то есть потоку пользовательского интерфейса), чтобы предотвратитьпроблемы с несколькими потоками.

Если вы используете Windows Forms, то .ObserveOnDispatcher() становится .ObserveOn(label1) или .ObserveOn(form), и все готово.

Не нужно гадить ос явно созданными потоками, таймерами или фоновыми работниками.

Вот ссылки для Rx:

0 голосов
/ 28 октября 2011

Это должно привести вас в правильном направлении.Я предполагаю, что вы создаете приложение 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();
    }
0 голосов
/ 28 октября 2011

Создайте форму с меткой с именем 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);
            }
        }
    }
}
...