螺纹内螺纹试图调用和更新UI [英] Thread inside thread trying to invoke and update ui
问题描述
我有一个文本框的WinForm和框TextChanged执行后台线程:
I have on winform with a textbox and on textchanged executes a background thread:
private void txtFathersLast_TextChanged(object sender, EventArgs e)
{
ThreadPool.QueueUserWorkItem(_ => WaitWhileUserTyping());
}
private void WaitWhileUserTyping()
{
var keepWaiting = true;
while (keepWaiting)
{
_keyPressed = false;
Thread.Sleep(TypingDelay);
keepWaiting = _keyPressed;
}
Invoke((MethodInvoker)(ExecuteSearch));
_waiting = false;
}
private void ExecuteSearch()
{
Thread.Sleep(200);
Task.Factory.StartNew(() =>
{
using (DataReference.SearchWCF search = new DataReference.SearchWCF())
{
_similaritySearchResults = search.SearchPersonBySimilarity(txtFathersLast.Text, txtMothersLast.Text, txtName.Text, DateTime.Now, 10);
}
}).ContinueWith(t=>{
if (this.InvokeRequired)
{
this.BeginInvoke(new Action(() =>
{
if (_similaritySearchResults != null && _similaritySearchResults.Tables["data"].Rows.Count > 0)
{
DataTable dt = _similaritySearchResults.Tables["data"];
Infragistics.Win.Misc.UltraTile newTile = null;
for (int index = 0; index < dt.Rows.Count; index++)
{
newTile = new Infragistics.Win.Misc.UltraTile("Person X");
newTile.Control = new CustomControls.Controls.PersonResult("123", "123", index + 150);
newTile.Tag = new Guid("90D27721-7315-4B86-9CFD-4F7D02921E9A");
newTile.DoubleClick += TileDoubleClick;
tilePanel.Tiles.Add(newTile);
}
}
}));
}
else
{
if (_similaritySearchResults != null && _similaritySearchResults.Tables["data"].Rows.Count > 0)
{
DataTable dt = _similaritySearchResults.Tables["data"];
Infragistics.Win.Misc.UltraTile newTile = null;
for (int index = 0; index < dt.Rows.Count; index++)
{
newTile = new Infragistics.Win.Misc.UltraTile("Person X");
newTile.Control = new CustomControls.Controls.PersonResult("123", "123", index + 150);
newTile.Tag = new Guid("90D27721-7315-4B86-9CFD-4F7D02921E9A");
newTile.DoubleClick += TileDoubleClick;
tilePanel.Tiles.Add(newTile);
}
}
}
}, TaskScheduler.FromCurrentSynchronizationContext());
}
这是工作的罚款,该应用程序进入到一个数据库,然后得到的结果和更新用户界面,增加瓷砖的不同按数据库返回的记录数的控制。
This is working fine, the application goes to a database then get results and update the UI, adding tiles to a control depending of the number of records returned by database.
现在,问题是当我尝试添加另一个后台线程进入我的自定义控件:
Now, the problem comes when I try to add another background thread into my custom control:
新CustomControls.Controls.PersonResult(123,123,指数+ 150);
new CustomControls.Controls.PersonResult("123", "123", index + 150);
在code的控制是:
protected override void InitLayout()
{
// if I comment this then everything works fine
// but if I leave this, then the UI freezes!!
GetPictureAsync();
base.InitLayout();
}
/// <summary>
///
/// </summary>
private void GetPictureAsync()
{
// This line needs to happen on the UI thread...
TaskScheduler uiScheduler = TaskScheduler.FromCurrentSynchronizationContext();
Task.Factory.StartNew(() =>
{
Random sleep = new Random();
System.Threading.Thread.Sleep(sleep.Next(1000,3000));
if (this.pbPhoto.InvokeRequired)
{
this.pbPhoto.Invoke(new Action(() =>
{
this.Load(@"E:\Photos\" + PhotoId.ToString() + ".jpg");
//this.pbPhoto.Image = Utility.Common.GetResourceImage("woman_sample.jpg");
}));
}
else
{
this.Load(@"E:\Photos\" + PhotoId.ToString() + ".jpg");
//this.pbPhoto.Image = Utility.Common.GetResourceImage("woman_sample.jpg");
}
}, CancellationToken.None, TaskCreationOptions.None, uiScheduler);
}
所以,问题似乎是我第一次执行一个线程希望何时开始搜索,那么该线程里面我为了获得数据库中的数据运行的另一个线程,然后在UI更新每个控制将运行另一个线程得到的图片和更新一个图片。
So the problem seems to be that I first execute a thread for looking when to start search, then inside that thread I run another thread in order to get data from database, and then each control updated in the UI will run another thread to get a picture and update a picturebox.
任何人知道如何解决这个问题?还是有办法来解决此问题?
Anyone knows how to solve this? or a way to work around this?
推荐答案
我觉得问题就出在你强迫任务 GetPictureAsync
来执行的UI线程,然后你呼吁 Thread.sleep代码()
。这<一个href=\"http://stackoverflow.com/questions/17418208/update-ui-in-task-using-taskscheduler-fromcurrentsynchronizationcontext\">update如您在使用TaskScheduler.FromCurrentSynchronizationContext 问题UI在任务铲球同样的问题。我会重写你的code为:
I think the problem lies in you forcing the Task in GetPictureAsync
to execute on UI thread and then you are calling Thread.Sleep()
. This update UI in Task using TaskScheduler.FromCurrentSynchronizationContext question tackles the same problem as you are having. I would rewrite your code as:
private void async GetPictureAsync()
{
Random sleep = new Random();
await TaskEx.Delay(sleep.Next(1000,3000));
this.Load(@"E:\Photos\" + PhotoId.ToString() + ".jpg");
}
这篇关于螺纹内螺纹试图调用和更新UI的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!