I have the following code:
private async void txtFirstName_TextChanged(object sender, EventArgs e)
{
_keyStrokeTime = DateTime.Now;
await KeyPressEvent();
}
On textchanged event I run an async task that will have to go and call a stored procedure to find matches and then return the number of firstname matches.
Here is the async Task method:
CancellationTokenSource source;
private async Task KeyPressEvent()
{
if(source != null)
source.Cancel(); // this communicates to your task running on another thread to cancel
source = new CancellationTokenSource();
var results = await Task.Run<object>(() => SqlSearch(source.Token));
if (results != null)
{
this.Invoke(new Action(() =>
{
pnlTiles.Controls.Clear();
CustomControl.PersonResult newPersonTile = null;
for (int index = 0; index < (int)results; index++)
{
newPersonTile = new CustomControl.PersonResult(index.ToString(), index.ToString());
pnlTiles.Controls.Add(newPersonTile );
}
}));
}
}
private object SqlSearch(CancellationToken token)
{
Random random = new Random();
object result = 1;
try
{
bool done= false;
while (true )
{
if(!done)
{
// random numbers to simulate number of results
result = random.Next(1, 13);
done = true;
}
token.ThrowIfCancellationRequested();
}
}
catch
{
return result;
}
}
The CustomControl.PersonResult control code is:
public partial class PersonResult : UserControl
{
private string _name = string.Empty;
private string _lastName = string.Empty;
public PersonResult()
: this("name", "last name")
{
}
public PersonResult(string name,string lastName)
{
InitializeComponent();
_name = name;
_lastName = lastName;
}
protected override void InitLayout()
{
// load photo
GetPictureAsync();
base.InitLayout();
}
/// <summary>
///
/// </summary>
private void GetPictureAsync()
{
// This line needs to happen on the UI thread...
// TaskScheduler uiScheduler = TaskScheduler.FromCurrentSynchronizationContext();
Task.Factory.StartNew(() =>
{
System.Threading.Thread.Sleep(3000);
if (this.pbPhoto.InvokeRequired)
{
this.pbPhoto.BeginInvoke(new Action(() =>
{
this.pbPhoto.Image = Utility.Common.GetResourceImage("woman_sample.jpg");
}));
}
else
{
this.pbPhoto.Image = Utility.Common.GetResourceImage("woman_sample.jpg");
}
});
}
}
Everything seems to work fine when I just type one letter in the TextBox, but if I keep typing maybe 6 letters I can see my CPU going to almost 50% to 90% of usage on my application process and stays there long time.
Im sure there is something wrong on the async methods, maybe when trying to set async the photo image to the CustomControl.
Can someone guide me on how to fix this?
Try this.