[C # .NET] [thread] Good use of SpinWaIt processing thread idle to improve performance

[C#.NET][Thread] Make good use of SpinWait to handle thread idling to improve performance

When we are processing a thread, if we need to wait synchronously, it’s possible in the past Thread.Sleep is often used, but Thread.Sleep consumes CPU time configuration, so we can use Thread.SpinWait method, SpinWait structure

Before .NET4.0, you can use Thread.SpinWait method

p>

The picture below is from http://msdn.microsoft.com/zh-tw/library/system.threading.thread.spinwait.aspx

image

in After .NET4.0, SpinWait structure can be used

The figure below is from http://msdn.microsoft.com/zh-tw/library/ee722114.aspx

image

The picture below is from http://msdn.microsoft.com/zh-tw/library/system.threading.spinwait.aspx

image

It seems that MSDN recommends using the SpinWait structure

Look at an example:

In the past, I used Stopwatch to match Thread.Sleep to achieve the purpose of idling waiting

p>


public void Start(Action action)
{
if (this.IsRunning)
{
return;
}

this.IsRunning = true;

Task.Factory.StartNew(() =>
{
Stopwatch watch = new Stopwatch();
while (this.IsRunning)
{
watch.Restart();
action.Invoke();

while (watch.ElapsedMilliseconds {
Thread.Sleep(1);
}
}
});
}

put this.Interval = 1 to observe the work manager As a result, the CPU used about 2% (this will have different results on different machines).

SNAGHTML137db49f_thumb

< p>

If Thread.Sleep(1) is removed, the CPU load will be nearly half loaded

SNAGHTML137f38fd_thumb


Now remove Thread.Sleep and use SpinWait.SpinUntil to run idle waiting instead.

image

< p>

The first parameter is the condition to leave idling, and the second parameter is the time to leave idling, as long as any parameter is satisfied, then idling will be left.


public void Start(Action action)
{
if (this.IsRunning)
{
return;
}

this.IsRunning = true;

Task.Factory.StartNew(() =>
{
while (this.IsRunning)
{
action.Invoke();
SpinWait.SpinUntil(() => !this.IsRunning, this.Interval);
}
});
}

We also use this.Interval = 1 to observe The effect of idling, the result is 0%, it is obvious that this way of writing is indeed better than the previous method.

SNAGHTML1385dd20_thumb

< p>

Conclusion:

PS. Basically, the faster the UI updates, the higher the CPU soars. If there is no idling UI, there is no way to update.

So we can replace Thread.Sleep(1) with SpinWait.SpinUntil(() => false, 1)


The complete program, it is not foolproof, Please do not set the TextBox to 0 or empty.


public class Polling
{
private int _interval = 1000;

public int Interval
{
get {return _interval;}
set {_interval = value;}
}
public bool IsRunning {get; internal set;}

public void Start(Action action)
{
if (this.IsRunning)
{
return;
}

this.IsRunning = true;

Task.Factory.StartNew(() =>
{
while (this.IsRunning)
{
action.Invoke();
SpinWait.SpinUntil(() => !this.IsRunning, this.Interval);
}
});
}

public void Stop()
{
if (!this.IsRunning)
{
return;
}
this.IsRunning = false;
}
}

Create a Winform project and create the following controls

image

User terminal, calling method, here is Use SynchronizationContext to update the UI


public partial class Form1: Form
{
public Form1()
{
InitializeComponent();
m_SynchronizationContext = SynchronizationContext.Current;
}

private SynchronizationContext m_SynchronizationContext;

private Polling _polling = new Polling();
private int _counter = 0;

private void button1_Click(object sender, EventArgs e)
{
this._polling.Interval = int.Parse(this.textBox1.Text);
this._polling.Start(() =>
{
this._counter++;
m_SynchronizationContext.Post(a => {this.label1.Text = this._counter.ToString(); }, null);
});
}

private void button2_Click(object sender, EventArgs e)
{
this._polling.Stop();
}
}

If there is a fallacy, please let me know, and novices please bear with me when posting

share pictures

 Share pictures 2010~2017 C# Fourth Season

Original: Large Column [C#.NET][Thread] Make good use of SpinWait to handle thread idling to improve performance

Leave a Comment

Your email address will not be published.