Создание программы с одиночными многопоточными C # - PullRequest
2 голосов
/ 30 сентября 2011

Я написал программу на C #. Теперь я закончил весь функционал и все работает. Но работает только с одним потоком. Я много вычисляю и иногда загружаю около 300 МБ или больше файлов измерений в приложение.

Теперь я хочу сделать программу многопоточной, потому что пользовательский опыт действительно плох во времена интенсивной обработки или операций ввода-вывода.

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

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

Я использовал более-менее чистую архитектуру MVC (Model View Control). Поэтому мне интересно, возможно ли позволить пользовательскому интерфейсу работать в одном потоке, а остальные приложения - в другом.

Если нет, загрузка и анализ 300 МБ, создание объектов займет около 3 минут, чтобы закончить. В это время пользователь не получает ответа от GUI. : /

UPDATE: Мои синглтоны используются как хранилище. Один синглтон сохраняет объекты проанализированных файлов измерений, а другой синглтон сохраняет результат. У меня разные расчеты, в которых используются одни и те же файлы измерений и создаются результаты, которые они хотят сохранить, используя другой синглтон. Это одна проблема.

Второе - заставить парня реагировать на действия пользователя или, по крайней мере, избегать этого предупреждения о том, что окно не отвечает.

Спасибо всем за все советы. Я попробую их. Извините за поздний ответ.

Ответы [ 3 ]

5 голосов
/ 30 сентября 2011

Обычно я избегаю одноэлементного паттерна, потому что он создает много проблем в будущем, особенно при тестировании. Тем не менее, есть довольно простое решение, чтобы заставить это работать для нескольких потоков, если вы хотите, чтобы один поток на поток. Поместите вашу ссылку-одиночка в поле (не свойство) и украсьте его с помощью ThreadStaticAttribute:

public class MySingleton
{
   [ThreadStatic]
   private static MySingletonClass _instance = new MySingletonClass();
   public static MySingletonClass Instance { get { return _instance; } }
}

Теперь у каждого потока будет свой экземпляр MySingleton.

1 голос
/ 30 сентября 2011

Самый простой способ - переместить все вычисления в один отдельный поток и обновить графический интерфейс, используя Invoke / InvokeRequired.

public partial class MyForm : Form
{
    Thread _workerThread;

    public MyForm()
    {
        _workerThread = new Thread(Calculate);
    }

    public void StartCalc()
    {
        _workerThread.Start();
    }

    public void Calculate()
    {
        //call singleton here


    }

    // true if user are allowed to change calc settings
    public bool CanUpdateSettings
    {
        get { return !_workerThread.IsAlive; } }
    }
}

Таким образом, вы получите графический интерфейс ответа, пока вычисленияБег.

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

Использование нескольких потоков для выполнения вычислений - гораздо более сложная история, котораянам нужно больше информации, чтобы дать вам правильный ответ.

0 голосов
/ 30 сентября 2011

Вы можете использовать TPL

Вы можете делать циклы с TPL параллельными, и, более того, они встроены в .NET 4.0, так что вам не нужно так сильно изменять свою программу

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...