Я пишу многопоточное приложение, это служба Windows. У меня 20 папок. Я создаю 15 потоков onstart метод. Я хочу добиться этого; 15 потоков идут в папки 1,2,3,..., 15 последовательно. Когда один поток завершен, он создает другой поток. Этот созданный поток должен перейти в папку 16.th. Он не должен идти в рабочие папки. Как я могу это сделать? То есть, как я могу быть уверенным, что два потока не идут в одну папку?
Не могли бы вы иметь статическую переменную, которая была бы счетчиком для имени папки?
Что-то вроде:
private static int _folderNameCounter = 0;
private static readonly object _padlock = new object();
public static int GetFolderCounter()
{
lock(_padlock)
{
_folderNameCounter++;
return _folderNameCounter;
}
}
public static void Main()
{
for(int i = 0; i < 20; i++)
{
Task.Factory.StartNew(() =>
{
var path = @"c:\temp\" + GetFolderCounter();
Directory.CreateDirectory(path);
// add your own code for the thread here
});
}
}
Примечание. Я использовал TPL вместо использования потоков напрямую, так как считаю, что TPL - лучшее решение. Конечно, у вас могут быть особые требования, которые могут означать, что Threads - лучшее решение для вашего дела.
Используйте BlockingCollection<T>
и заполните коллекцию номерами папок. Каждая задача обрабатывает элемент коллекции, и сама коллекция обрабатывает многопоточность, так что каждый элемент обрабатывается только одним пользователем.
// Define the blocking collection with a maximum size of 15.
const int maxSize = 15;
var data = new BlockingCollection<int>(maxSize);
// Add the data to the collection.
// Do this in a separate task since BlockingCollection<T>.Add()
// blocks when the specified capacity is reached.
var addingTask = new Task(() => {
for (int i = 1; i <= 20; i++) {
data.Add(i);
}
).Start();
// Define a signal-to-stop bool
var stop = false;
// Create 15 handle tasks.
// You can change this to threads if necessary, but the general idea is that
// each consumer continues to consume until the stop-boolean is set.
// The Take method returns only when an item is/becomes available.
for (int t = 0; t < maxSize; t++) {
new Task(() => {
while (!stop) {
int item = data.Take();
// Note: the Take method will block until an item comes available.
HandleThisItem(item);
}
}).Start();
};
// Wait until you need to stop. When you do, set stop true
stop = true;