Это просто ситуация самообучения. Я новичок в TPL и Threading. В любом случае, я использую общий c Singleton-класс и создаю ~ 10K экземпляров, чтобы каждый раз проверять, возвращает ли мой код тот же экземпляр или каждый раз создает новый экземпляр. Я создаю экземпляры асинхронно, используя Task Factory внутри for l oop. Чтобы проверить создание экземпляра, я возвращаю строку с этой информацией в виде списка строк:
- Счетчик итераций
- Имя экземпляра
- Хэш-код экземпляра и
- ThreadId и отображение списка строк в списке.
Мои запросы
При запуске я обнаружил несколько вещей,
- значение i внутри for l oop дублируется для разных intances
- для этих 10K итераций, у меня создано только 8-9 потоков вместо ожидаемых 10k потоков. Я ожидал, что 10K потоков будут всплывать, выполнять свою индивидуальную задачу и затем плавно исчезать. *
Пожалуйста, оставьте заметку в моих мыслях по теме 1OK :). Хорошая / плохая идея для многопоточности?
Мой код
Singleton Class
public sealed class Singleton<T> where T : class
{
static Singleton() { }
private Singleton() { }
public static T Instance { get; } = Activator.CreateInstance<T>();
}
Class: SingletonInThread
public class SingletonInThread
{
/// <summary>
/// Method responsible for creation of same instance, 10K times using Task.Factory.StartNew()
/// </summary>
/// <returns></returns>
public async Task<IEnumerable<string>> LoopAsync()
{
List<Task<string>> list = new List<Task<string>>();
for (int i = 0; i <= 9999; i++)
{
list.Add(Task.Factory.StartNew(()=> CreateAndLogInstances(i)));
}
return await Task.WhenAll<string>(list);
}
/// <summary>
/// Creates new instance of Logger and logs its creation with few details. Kind of Unit of Work.
/// </summary>
/// <param name="i"></param>
/// <returns></returns>
private string CreateAndLogInstances(int i)
{
var instance = Singleton<Logger>.Instance;
return $"Instance{i}. Name of instance= {instance.ToString()} && Hashcode ={instance.GetHashCode()} && ThreadId= {Thread.CurrentThread.ManagedThreadId}";
}
}
Frontend _ На стороне пользовательского интерфейса событие On buttonclick, заполнение списка
private async void button1_Click(object sender, EventArgs e)
{
IEnumerable<string> list = await new SingletonInThread().LoopAsync();
foreach (var item in list)
{
listBox1.Items.Add(item);
}
}
Кроме того, я заметил одну вещь, что мой пользовательский интерфейс блокируется при заполнении окна списка 10K элементами. Пожалуйста, помогите мне заполнить его асинхронным способом. Я знал bgworker, begininvoke и methodinvoker. Есть ли что-нибудь кроме тоже в TPL ??
Output
введите описание изображения здесь
---
Обновление
Как было предложено, если я использую Parallel.For, тогда вместо строк 10K я получаю случайное число 9491, 9326 и др. c. Т.е. меньше 10К. Я не знаю, почему ????
Вот мой обновленный код для метода LoopAsyn c с использованием Parallel.For
public IEnumerable<string> LoopAsync()
{
List<string> list = new List<string>();
Parallel.For(0, 9999, i =>
{
list.Add( CreateAndLogInstances(i));
});
return list;
}