С Новым годом! Форум программистов, компьютерный форум, киберфорум
C# Windows Forms
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.92/13: Рейтинг темы: голосов - 13, средняя оценка - 4.92
 Аватар для Midian
606 / 388 / 198
Регистрация: 31.03.2013
Сообщений: 2,689

Прикрутить многопоточность, чтобы загрузка Excel в массив происходила в другом потоке

27.09.2014, 23:06. Показов 2945. Ответов 5
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Решил написать небольшую программку парсер Excel, все сделал, работает, но решил прикрутить многопоточность, чтобы загрузка Excel в массив происходила в другом потоке и столкнулся с проблемой, понимаю что нужно использовать метод Invoke, но нету времени с ним разбираться, помогите прикрутить его в моему проекту (нужно чтобы функция FileExcelLoad выполнялась в другом потоке), вот мой код, спасибо заранее за помощь.
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
using System;
using System.ComponentModel;
using System.Reflection;
using System.Threading;
using System.Windows.Forms;
 
namespace ParsingExcel
{
    public partial class MainForm : Form
    {
        string[] arr;
 
        public MainForm()
        {
            InitializeComponent();
            textBoxSearch.KeyDown += new KeyEventHandler(keyDown);
        }
 
        private void Search()
        {
            string searchValue = null; int i = 12;
            Microsoft.Office.Interop.Excel.Application ObjWorkExcel = new Microsoft.Office.Interop.Excel.Application();
            Microsoft.Office.Interop.Excel.Workbook ObjWorkBook = ObjWorkExcel.Workbooks.Open(openFileDialogMain.FileName, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
            Microsoft.Office.Interop.Excel.Worksheet ObjWorkSheet = (Microsoft.Office.Interop.Excel.Worksheet)ObjWorkBook.Sheets[1];
            try
            {
                foreach (var search in arr)
                {
                    i++; string[] tempArr = null;
                    if (search != null)
                    {
                        tempArr = search.Split(' ');
                        if (tempArr[tempArr.Length - 1] == textBoxSearch.Text)
                        {
                            searchValue = search;
                            ObjWorkSheet.Cells[i, int.Parse(textBoxNumber.Text)].Interior.ColorIndex = 6;
                        }
                    }
                }
            }
            finally
            {
                ObjWorkBook.Close(true, Type.Missing, Type.Missing);
                ObjWorkExcel.Quit(); GC.Collect();
            }
            if (searchValue == null)
                MessageBox.Show("Нет такой записи в столбце, укажите другую запись, или номер столбца.", "Запись не найдена.", MessageBoxButtons.OK);
            else MessageBox.Show("Запись найдена и выделена", "Запись найдена", MessageBoxButtons.OK);
        }
 
        private void FileExcelLoad()
        {
            openFileDialogMain.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
            openFileDialogMain.Filter = "xlsx files (*.xlsx)|*.xlsx|All files (*.*)|*.*";
            openFileDialogMain.FilterIndex = 2;
            openFileDialogMain.RestoreDirectory = true;
            if (openFileDialogMain.ShowDialog() == DialogResult.OK)
            {
                textBoxFile.Text = openFileDialogMain.FileName;
                Microsoft.Office.Interop.Excel.Application ObjWorkExcel = new Microsoft.Office.Interop.Excel.Application();
                Microsoft.Office.Interop.Excel.Workbook ObjWorkBook = ObjWorkExcel.Workbooks.Open(openFileDialogMain.FileName, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
                Microsoft.Office.Interop.Excel.Worksheet ObjWorkSheet = (Microsoft.Office.Interop.Excel.Worksheet)ObjWorkBook.Sheets[1];
                var lastCell = ObjWorkSheet.Cells.SpecialCells(Microsoft.Office.Interop.Excel.XlCellType.xlCellTypeLastCell);
                arr = new string[(int)lastCell.Row];
                try
                {
                    progressBarLoadingExcelFile.Visible = true;
                    progressBarLoadingExcelFile.Maximum = (int)lastCell.Row;
                    for (int i = 12; i < (int)lastCell.Row; i++)
                    {
                        arr[i - 12] = ObjWorkSheet.Cells[i + 1, int.Parse(textBoxNumber.Text)].Text.ToString();
                        progressBarLoadingExcelFile.Value = i;
                    }
                }
                finally
                {
                    ObjWorkBook.Close(false, Type.Missing, Type.Missing);
                    ObjWorkExcel.Quit(); GC.Collect();
                    progressBarLoadingExcelFile.Visible = false;
                }
            }
        }
 
        private void keyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter) buttonSearch_Click(new object(), new EventArgs());
        }
 
        private void buttonFile_Click(object sender, EventArgs e)
        {
            Thread thread = new Thread(new ThreadStart(FileExcelLoad));
            thread.Start();
        }
 
        private void buttonSearch_Click(object sender, EventArgs e)
        {
            Thread thread = new Thread(new ThreadStart(Search));
            thread.Start();
        }
 
        private void textBoxNumber_TextChanged(object sender, EventArgs e)
        {
            int numberRows;
            if (int.TryParse(textBoxNumber.Text, out numberRows))
                buttonFile.Enabled = true;
            else buttonFile.Enabled = false;
        }
 
        private void textBoxSearch_TextChanged(object sender, EventArgs e)
        {
            if (!String.IsNullOrEmpty(textBoxNumber.Text))
                buttonSearch.Enabled = true;
            else buttonSearch.Enabled = false;
        }
    }
}
Добавлено через 1 минуту
Отваливается с ошибкой:
Текущий поток должен быть задан как поток однопоточного контейнера (STA), чтобы вызовы OLE стали возможны. Проверьте, что ваша функция Main помечена атрибутом STAThreadAttribute. Данное исключение создается, только если к процессу подключен отладчик.
На строчке с
C#
1
if (openFileDialogMain.ShowDialog() == DialogResult.OK)
Добавлено через 38 секунд
Делал пометку, ничего не помогло, подозреваю что нужен метод Invoke

Добавлено через 7 часов 31 минуту
Печаль что никто не дал идею, буду завтра думать сам...
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
27.09.2014, 23:06
Ответы с готовыми решениями:

Открывать excel файл в другом потоке
Добрый всем день! Подскажите пожалуйста, как открывать большие excel файлы в другом потоке, чтобы программа не зависала при добавлении...

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

Как получить значение переменной созданной в потоке, в другом потоке?
Добрый день :) Возник такой вопрос &quot;как получить значение переменной созданной в потоке, в другом потоке?&quot; Не знаю, как правильно...

5
Эксперт .NET
 Аватар для insite2012
5548 / 4311 / 1218
Регистрация: 12.10.2013
Сообщений: 12,371
Записей в блоге: 2
28.09.2014, 08:36
Midian, проверьте в файле с методом Main() (если правильно помню, по умолчанию он в проекте называется Program.cs), помечен ли метод атрибутом STAThreadAttribute.
0
 Аватар для Midian
606 / 388 / 198
Регистрация: 31.03.2013
Сообщений: 2,689
28.09.2014, 10:12  [ТС]
Странно, но он у меня по умолчанию помечен:
C#
1
2
3
4
5
6
7
[STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new MainForm());
        }
Добавлено через 6 минут
Нашел похожую тему, но у меня нет никаких длл-ок, у меня есть функция, которую я пытаюсь запустить в отдельном потоке.
Текущий поток должен быть задан как поток однопоточного контейнера (STA), чтобы вызовы OLE стали возможны

Добавлено через 15 минут
В общем нашел решение сам, вот что нужно было сделать:
C#
1
2
3
            Thread thread = new Thread(new ThreadStart(FileExcelLoad));
            thread.SetApartmentState(ApartmentState.STA);
            thread.Start();
0
Эксперт .NET
 Аватар для insite2012
5548 / 4311 / 1218
Регистрация: 12.10.2013
Сообщений: 12,371
Записей в блоге: 2
28.09.2014, 10:13
Лучший ответ Сообщение было отмечено Midian как решение

Решение

Midian, судя по коду, вы пытаетесь из отдельного потока обратиться к GUI. Верно? Вероятнее всего, потому и вываливается у вас ошибка. Используйте
C#
1
this.Invoke((Action)delegate{//Тут обращение к контролам формы...});
P.S. Писал прямо тут, может не совсем корректно, но смысл ясен, ятд...
0
 Аватар для Midian
606 / 388 / 198
Регистрация: 31.03.2013
Сообщений: 2,689
28.09.2014, 10:18  [ТС]
А теперь уже другая ошибка
Недопустимая операция в нескольких потоках: попытка доступа к элементу управления 'textBoxFile' не из того потока, в котором он был создан.
На строке
C#
1
textBoxFile.Text = openFileDialogMain.FileName;
Добавлено через 3 минуты
insite2012, Спасибо тебе, написал вот так и все заработало:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
        private void FileExcelLoad()
        {
            openFileDialogMain.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
            openFileDialogMain.Filter = "xlsx files (*.xlsx)|*.xlsx|All files (*.*)|*.*";
            openFileDialogMain.FilterIndex = 2;
            openFileDialogMain.RestoreDirectory = true;
            if (openFileDialogMain.ShowDialog() == DialogResult.OK)
            {
                this.Invoke((Action)delegate { textBoxFile.Text = openFileDialogMain.FileName; });
                Microsoft.Office.Interop.Excel.Application ObjWorkExcel = new Microsoft.Office.Interop.Excel.Application();
                Microsoft.Office.Interop.Excel.Workbook ObjWorkBook = ObjWorkExcel.Workbooks.Open(openFileDialogMain.FileName, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
                Microsoft.Office.Interop.Excel.Worksheet ObjWorkSheet = (Microsoft.Office.Interop.Excel.Worksheet)ObjWorkBook.Sheets[1];
                var lastCell = ObjWorkSheet.Cells.SpecialCells(Microsoft.Office.Interop.Excel.XlCellType.xlCellTypeLastCell);
                arr = new string[(int)lastCell.Row];
                try
                {
                    this.Invoke((Action)delegate { progressBarLoadingExcelFile.Visible = true; });
                    this.Invoke((Action)delegate { progressBarLoadingExcelFile.Maximum = (int)lastCell.Row; });
                    for (int i = 12; i < (int)lastCell.Row; i++)
                    {
                        arr[i - 12] = ObjWorkSheet.Cells[i + 1, int.Parse(textBoxNumber.Text)].Text.ToString();
                        this.Invoke((Action)delegate { progressBarLoadingExcelFile.Value = i; });
                    }
                }
                finally
                {
                    ObjWorkBook.Close(false, Type.Missing, Type.Missing);
                    ObjWorkExcel.Quit(); GC.Collect();
                    this.Invoke((Action)delegate { progressBarLoadingExcelFile.Visible = false; });
                }
            }
        }
0
Эксперт .NET
 Аватар для insite2012
5548 / 4311 / 1218
Регистрация: 12.10.2013
Сообщений: 12,371
Записей в блоге: 2
28.09.2014, 10:29
Midian,
Цитата Сообщение от insite2012 Посмотреть сообщение
this.Invoke
this.Invoke можно не повторять каждый раз, а написать один раз и между фигурными скобками ставить все операторы обращения к контролам.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
28.09.2014, 10:29
Помогаю со студенческими работами здесь

Работа с Dictionary в одном потоке, при этом он может изменятся в другом потоке
Здравствуйте! Я делаю лабу сервер распределенных вычислений в сети. В одном потоке ожидаю клиентов и на каждого клиента создаю поток. ...

Элементы управления, созданные в одном потоке, не могут быть родительскими для элемента управления в другом потоке
Привет :) Есть задача - нужно динамически добавлять компоненты. Все работает хорошо. Но если добавлять через цикл то начинает зависать...

Переделать код, чтобы происходила запись в файл
Было задание: В столовой предлагается N комплексных обедов из Q блюд. Известна стоимость и калорийность каждого блюда. Сколько стоит самый...

Как сделать, чтобы по нажатию кнопки не происходила перезагрузка страницы?
Доброго дня, есть форма &lt;form action=&quot;save_stavka.php&quot; method=&quot;post&quot;&gt; Сделать ставку&lt;input name=&quot;summa&quot; type=&quot;text&quot;...

Изменить код программы так чтобы работа происходила с консолью а не с файлом
Помогите изменить код программы так чтобы работа происходила с консолью а не с файлом. USES Crt; TYPE path = STRING; Stroca =...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
Новые блоги и статьи
Модель микоризы: классовый агентный подход
anaschu 02.01.2026
Раньше это было два гриба и бактерия. Теперь три гриба, растение. И на уровне агентов добавится между грибами или бактериями взаимодействий. До того я пробовал подход через многомерные массивы,. . .
Учёным и волонтёрам проекта «Einstein@home» удалось обнаружить четыре гамма-лучевых пульсара в джете Млечного Пути
Programma_Boinc 01.01.2026
Учёным и волонтёрам проекта «Einstein@home» удалось обнаружить четыре гамма-лучевых пульсара в джете Млечного Пути Сочетание глобально распределённой вычислительной мощности и инновационных. . .
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод Нашел на реддите интересную статью под названием The Thinkpad X220 Tablet is the best budget school laptop period . Ниже её машинный перевод. Thinkpad X220 Tablet —. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru