Клиет находится
тут, сервер вот он:
[ServiceContract]
public interface IThread {
[OperationContract]
void Start(int nTasks, int nActions);
[OperationContract]
byte[] Status();
[OperationContract]
int StatusSimple();
}
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Single, UseSynchronizationContext=false)]
public class WebThread : IThread {
public WebThread() {
//Thread.CurrentThread.Priority = ThreadPriority.Highest;
//Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.RealTime;
graphics = Graphics.FromImage(bitmap);
}
public void Start(int nTasks, int nActions) {
bitmap = new Bitmap(Width, (nTasks+1)*10);
graphics= Graphics.FromImage(bitmap);
x=0;
for (int i = 1; i<= nTasks; ++i) {
var n = i;
Task.Factory.StartNew(() => {
doWork(n, nActions);
});
//new Thread(() => {
// doWork(n,qActions);
//}).Start();
}
}
public byte[] Status() {
using (var ms = new MemoryStream()) {
lock(bitmap)
bitmap.Save(ms, ImageFormat.Png);
return ms.ToArray();
}
}
public int StatusSimple() {
return n++;
}
private int n=0;//номер обращения
private void doWork(int n, int qActions) {
Thread.CurrentThread.Priority = ThreadPriority.Lowest;//наполовину помогло
for (int j =0; j<qActions; j++) {
for (var k=0; k<1000000; ++k)
v1=1/(j+rnd.NextDouble());
log(n);
}
logEnd(n);
}
private void log(int n) {
lock (bitmap) {
graphics.DrawLine(new Pen(Color.Black), x, n*10, x, (n+1)*10-1);
x++;
}
}
private void logEnd(int n){
lock (bitmap) {
graphics.FillRectangle(new SolidBrush(Color.LightBlue), x, n*10, Width-x, 10);
x++;
}
}
private int Width = 1700;
private int x = 0;
private Bitmap bitmap = new Bitmap(1, 1);
private Graphics graphics;
private readonly Random rnd = new Random();
private double v1;
}
Веб-клиент по кнопке запускает Start() и ежесекундно дёргает Status() и StatusSimple().
Status() и StatusSimple() задуманы как быстрые функции опроса текущего состояния результатов фоновой работы, и мне кажется, никакая асинхронность в них не нужна, т.к. задача в том что бы эти функции быстро отрабатывали сразу, а не откладывали дополнительно получения статусов на потом.
По своим экспериментам вижу, что фоновые потоки не дают отрабатывать Status() и StatusSimple() довольно долго. Выставление приоритетов помогает частично. Всё равно основной поток намного хуже работает GUI потока активного окна в случае десктопа.