.NET: То, как иметь основные данные потока сигнала фонового потока, доступно?

C99 N1256 стандартная черновик

http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf

6.5.3.4 Оператор sizeof :

3 При применении к операнду, который имеет структуру или тип объединения, результатом является общее количество байтов в таких объект, включая внутреннюю и конечную прокладку.

blockquote>

6.7.2.1 Спецификаторы структуры и объединения :

13 ... Там может быть неназванным дополнением внутри объекта структуры, но не в начале.

blockquote>

и:

15 В конце структуры может быть неназванное дополнение или объединение.

blockquote>

Новая функция члена C99 с гибким элементом массива (struct S {int is[];};) также может влиять на заполнение:

16 As в специальном случае последний элемент структуры с более чем одним именованным элементом может иметь неполный тип массива; это называется гибким элементом массива. В большинстве ситуаций гибкий элемент массива игнорируется. В частности, размер структуры выглядит так, как если бы гибкий элемент массива был пропущен, за исключением того, что он мог иметь более длинное дополнение, чем подразумевалось.

blockquote>

Приложение J Проблемы с переносимостью повторяет:

Следующие неуказаны: ...

  • Значение байтов заполнения при хранении значений в структурах или объединениях (6.2.6.1)
blockquote>

C ++ 11 Стандартная черновая версия N3337

http://www.open-std.org/jtc1/sc22/wg21/ docs / papers / 2012 / n3337.pdf

5.3.3 Размер :

2 При применении к классу результатом является количество байтов в объекте этого класса, включая любое дополнение, необходимое для размещения объектов этого типа в массиве.

blockquote>

9.2 Члены класса :

Указатель на объект структуры стандартного макета, соответствующим образом преобразованный с использованием reinterpret_cast, указывает на его начальный член (или если этот элемент является битовым полем, то t o единица, в которой он находится) и наоборот. [Примечание. Таким образом, в рамках объекта структуры стандартного макета может быть указано неназванное заполнение, но не в его начале, по мере необходимости, для достижения соответствующего выравнивания. - end note]

blockquote>

Я знаю достаточно C ++, чтобы понять примечание: -)

11
задан Ian Boyd 23 September 2008 в 18:45
поделиться

7 ответов

Вот пример кода для Системы. ComponentModel. Класс BackgroundWorker.

    private static BackgroundWorker worker = new BackgroundWorker();
    static void Main(string[] args)
    {
        worker.DoWork += worker_DoWork;
        worker.RunWorkerCompleted += worker_RunWorkerCompleted;
        worker.ProgressChanged += worker_ProgressChanged;
        worker.WorkerReportsProgress = true;

        Console.WriteLine("Starting application.");
        worker.RunWorkerAsync();

        Console.ReadKey();
    }

    static void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        Console.WriteLine("Progress.");
    }

    static void worker_DoWork(object sender, DoWorkEventArgs e)
    {
        Console.WriteLine("Starting doing some work now.");

        for (int i = 0; i < 5; i++)
        {
            Thread.Sleep(1000);
            worker.ReportProgress(i);
        }
    }

    static void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        Console.WriteLine("Done now.");
    }
11
ответ дан 3 December 2019 в 06:49
поделиться

Я комбинирую несколько ответов здесь.

Идеальная ситуация использует ориентированный на многопотоковое исполнение флаг такой в качестве AutoResetEvent. Вы не должны блокироваться неограниченно долго, когда Вы звоните WaitOne(), на самом деле это имеет перегрузку, которая позволяет Вам указывать тайм-аут. Эта перегрузка возвраты false если флаг не был установлен во время интервала.

A Queue более идеальная структура для отношений производителя/потребителя, но можно подражать ему, если требования вынуждают Вас использовать a List. Существенное различие, Вы оказываетесь перед необходимостью удостоверяться, что Ваш потребитель блокирует доступ к набору, в то время как это извлекает объекты; самая безопасная вещь состоит в том, чтобы, вероятно, использовать CopyTo метод для копирования всех элементов в массив затем выпустите блокировку. Конечно, удостоверьтесь, что Ваш производитель не попытается обновить List в то время как блокировка сохранена.

Вот простое консольное приложение C#, которое демонстрирует, как это могло бы быть реализовано. Если Вы играете вокруг с интервалами синхронизации, можно вызвать различные вещи произойти; в этой конкретной конфигурации я пытался сделать, чтобы производитель генерировал несколько объектов перед потребительскими проверками на объекты.

using System;
using System.Collections.Generic;
using System.Threading;

namespace ConsoleApplication1
{
    class Program
    {
        private static object LockObject = new Object();

        private static AutoResetEvent _flag;
        private static Queue<int> _list;

        static void Main(string[] args)
        {
            _list = new Queue<int>();
            _flag = new AutoResetEvent(false);

            ThreadPool.QueueUserWorkItem(ProducerThread);

            int itemCount = 0;

            while (itemCount < 10)
            {
                if (_flag.WaitOne(0))
                {
                    // there was an item
                    lock (LockObject)
                    {
                        Console.WriteLine("Items in queue:");
                        while (_list.Count > 0)
                        {
                            Console.WriteLine("Found item {0}.", _list.Dequeue());
                            itemCount++;
                        }
                    }
                }
                else
                {
                    Console.WriteLine("No items in queue.");
                    Thread.Sleep(125);
                }
            }
        }

        private static void ProducerThread(object state)
        {
            Random rng = new Random();

            Thread.Sleep(250);

            for (int i = 0; i < 10; i++)
            {
                lock (LockObject)
                {
                    _list.Enqueue(rng.Next(0, 100));
                    _flag.Set();
                    Thread.Sleep(rng.Next(0, 250));
                }
            }
        }
    }
}

Если Вы не хотите блокировать производителя вообще, это немного более хитро. В этом случае я предложил бы делать производителя его собственным классом и с частным и с общедоступным буфером и общественностью AutoResetEvent. Производитель будет объектами хранилища по умолчанию в частном буфере, затем пытаться записать им в общедоступный буфер. Когда потребитель работает с общедоступным буфером, он сбрасывает флаг на объекте производителя. Прежде чем производитель пытается переместить объекты с частного буфера на общедоступный буфер, он проверяет этот флаг и только копирует объекты, когда потребитель не работает над ним.

3
ответ дан 3 December 2019 в 06:49
поделиться

Если Вы используете backgroundworker, чтобы запустить второй поток и использовать событие ProgressChanged, чтобы уведомить другой поток, что данные готовы. Другие события доступны также. Эта статья MSDN должна запустить Вас.

1
ответ дан 3 December 2019 в 06:49
поделиться

Существует много способов сделать это, в зависимости от точно, что Вы хотите сделать. Очередь производителя/потребителя, вероятно, что Вы хотите. Для превосходного всестороннего взгляда в потоки см. главу по Поточной обработке (доступный онлайн) от превосходного книжного C# 3.0 вкратце.

1
ответ дан 3 December 2019 в 06:49
поделиться

Можно использовать AutoResetEvent (или ManualResetEvent). Если Вы используете AutoResetEvent. WaitOne (0, ложь), это не заблокируется. Например:

AutoResetEvent ev = new AutoResetEvent(false);
...
if(ev.WaitOne(0, false)) {
  // event happened
}
else {
 // do other stuff
}
1
ответ дан 3 December 2019 в 06:49
поделиться

Класс BackgroundWorker является ответом в этом случае. Это - единственная конструкция поточной обработки, которая может асинхронно отправить сообщения в поток, который создал объект BackgroundWorker. Внутренне BackgroundWorker использование AsyncOperation класс путем вызова asyncOperation.Post() метод.

this.asyncOperation = AsyncOperationManager.CreateOperation(null);
this.asyncOperation.Post(delegateMethod, arg);

Несколько других классов в платформе.NET также используют AsyncOperation:

  • BackgroundWorker
  • SoundPlayer. LoadAsync ()
  • SmtpClient. SendAsync ()
  • Ping. SendAsync ()
  • WebClient. DownloadDataAsync ()
  • WebClient. DownloadFile ()
  • WebClient. DownloadFileAsync ()
  • WebClient...
  • PictureBox. LoadAsync ()
1
ответ дан 3 December 2019 в 06:49
поделиться

Если Ваш "основной" поток является насосом сообщения Windows (GUI) поток, то можно опросить использование Формы. Таймер - настраивает интервал таймера согласно тому, как быстро у Вас должно быть свое 'уведомление' потока GUI данные из рабочего потока.

Не забудьте синхронизировать доступ к общему List<> если Вы собираетесь использовать foreach, избегать CollectionModified исключения.

Я использую эту технику для всех управляемых данными рынком обновлений GUI в торговом приложении в реальном времени, и она работает очень хорошо.

0
ответ дан 3 December 2019 в 06:49
поделиться
Другие вопросы по тегам:

Похожие вопросы: