Я хочу оптимизировать скорость и производительность моей серверной части для управления клиентами, я думаю, что у меня есть два способа управления ими:
1.Создать вручную один поток на соединение клиента
2.создать SynchronizationContext для каждого клиента (это будет управлять потоками в фоновом режиме)
Предположим, у нас подключен миллион пользователей:
Первый способ быстрее, но я не знаю, оптимизировать и лучше управлятьотправлять / получать данные от клиента или нет?
Что вы предлагаете для повышения производительности и скорости управления всеми клиентами без задержек и зависаний?
Мой пример тестирования SynchronizationContext и многопоточности наконсоль:
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace SynchronizationContextForMethod
{
public class ServiceClass
{
public void Login(string name)
{
OperationContext<ClientInfo>.Current = new ClientInfo() { Name = name };
}
public string WhatIsMyName()
{
return OperationContext<ClientInfo>.Current.Name;
}
}
public class ClientInfo
{
public string Name { get; set; }
public string UserName { get; set; }
}
public class OperationContext<T>
{
static ConcurrentDictionary<SynchronizationContext, T> ContextByThread = new ConcurrentDictionary<SynchronizationContext, T>();
public static T Current
{
get
{
ContextByThread.TryGetValue(SynchronizationContext.Current, out T value);
return value;
}
set
{
ContextByThread.TryAdd(SynchronizationContext.Current, value);
}
}
public static void EncContext()
{
ContextByThread.TryRemove(SynchronizationContext.Current, out T value);
}
}
class Program
{
static List<SynchronizationContext> _contexts = new List<SynchronizationContext>();
static void Main(string[] args)
{
ThreadPool.GetMaxThreads(out int worker, out int ports);
ThreadPool.SetMaxThreads(int.MaxValue, int.MaxValue);
Console.WriteLine("thread count : " + Process.GetCurrentProcess().Threads.Count);
SynchronizationContext.SetSynchronizationContext(new SynchronizationContext());
_contexts.Add(SynchronizationContext.Current);
var service = new ServiceClass();
for (int i = 0; i < 20; i++)
{
//PostWithNewThread((state) =>
PostNormally((state) =>
{
GC.Collect();
if (SynchronizationContext.Current == null)
{
SynchronizationContext.SetSynchronizationContext(new SynchronizationContext());
}
else
{
//no run ever
}
Console.WriteLine("thread count : " + Process.GetCurrentProcess().Threads.Count);
var name = state.ToString();
service.Login(name);
var isTrue = name == service.WhatIsMyName();
if (!isTrue)
{
//if false this is wrong code!
}
Console.WriteLine($"service login {name}: " + isTrue);
Thread.Sleep(5000);
Console.WriteLine($"service " + name + " finished");
OperationContext<ClientInfo>.EncContext();
}, "ali" + i);
Console.WriteLine("thread count : " + Process.GetCurrentProcess().Threads.Count);
//PostWithNewThread((state) =>
PostNormally((state) =>
{
GC.Collect();
if (SynchronizationContext.Current == null)
{
SynchronizationContext.SetSynchronizationContext(new SynchronizationContext());
}
else
{
//no run ever
}
Console.WriteLine("thread count : " + Process.GetCurrentProcess().Threads.Count);
var name = state.ToString();
service.Login(name);
var isTrue = name == service.WhatIsMyName();
if (!isTrue)
{
//if false this is wrong code!
}
Console.WriteLine($"service login {name}: " + isTrue);
Console.WriteLine($"service " + name + " finished");
OperationContext<ClientInfo>.EncContext();
}, "reza" + i);
Console.WriteLine("thread count : " + Process.GetCurrentProcess().Threads.Count);
//PostWithNewThread((state) =>
PostNormally((state) =>
{
GC.Collect();
if (SynchronizationContext.Current == null)
{
SynchronizationContext.SetSynchronizationContext(new SynchronizationContext());
}
else
{
//no run ever
}
Console.WriteLine("thread count : " + Process.GetCurrentProcess().Threads.Count);
Thread.Sleep(2000);
var name = state.ToString();
service.Login(name);
var isTrue = name == service.WhatIsMyName();
if (!isTrue)
{
//if false this is wrong code!
}
Console.WriteLine($"service login {name}: " + (isTrue));
Console.WriteLine($"service " + name + " finished");
OperationContext<ClientInfo>.EncContext();
}, "hassan" + i);
}
Console.WriteLine("thread count : " + Process.GetCurrentProcess().Threads.Count);
while (true)
{
GC.Collect();
Thread.Sleep(1000);
Console.WriteLine("thread count : " + Process.GetCurrentProcess().Threads.Count);
}
}
public static void PostNormally(SendOrPostCallback run, object state)
{
SynchronizationContext.Current.Post(run, state);
}
public static void PostWithNewThread(SendOrPostCallback run, object state)
{
Thread thread = new Thread(() =>
{
run(state);
});
thread.IsBackground = true;
thread.Start();
}
}
}