C# 试图调用和更新ui的线程中的线程

C# 试图调用和更新ui的线程中的线程,c#,multithreading,winforms,asynchronous,async-await,C#,Multithreading,Winforms,Asynchronous,Async Await,我在winform上有一个文本框,在textchanged上执行一个后台线程: private void txtFathersLast_TextChanged(object sender, EventArgs e) { ThreadPool.QueueUserWorkItem(_ => WaitWhileUserTyping()); } private void WaitWhileUserTyping() { var keepWaiting = tr

我在winform上有一个文本框,在textchanged上执行一个后台线程:

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());


        }
private void txtfatherlast\u text已更改(对象发送方,事件参数e)
{
ThreadPool.QueueUserWorkItem(=>WaitWhileUserTyping());
}
私有void WaitWhileUserTyping()
{
var keepWaiting=true;
同时(保持等待)
{
_按键=假;
线程。睡眠(键入延迟);
keepWaiting=_键按下;
}
调用((MethodInvoker)(ExecuteSearch));
_等待=错误;
}
私有void ExecuteSearch()
{
睡眠(200);
Task.Factory.StartNew(()=>
{
使用(DataReference.SearchWCF search=newdatareference.SearchWCF())
{
_similaritySearchResults=search.SearchPersonBySimilarity(txtfaterslast.Text,txtMothersLast.Text,txtName.Text,DateTime.Now,10);
}
}).ContinueWith(t=>{
if(this.invokererequired)
{
此.BeginInvoke(新操作(()=>
{
if(_similaritySearchResults!=null&&u similaritySearchResults.Tables[“data”]。Rows.Count>0)
{
DataTable dt=_similaritySearchResults.Tables[“data”];
Infragistics.Win.Misc.UltraTile新文件=空;
对于(int index=0;index0)
{
DataTable dt=_similaritySearchResults.Tables[“data”];
Infragistics.Win.Misc.UltraTile新文件=空;
对于(int index=0;index
这工作正常,应用程序进入数据库,然后获取结果并更新UI,根据数据库返回的记录数向控件添加平铺

现在,当我尝试将另一个后台线程添加到自定义控件中时,问题出现了:

新的CustomControls.Controls.PersonResult(“123”,“123”,索引+150)

控件的代码为:

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);
        }
protected override void InitLayout()
{
//如果我对此发表评论,那么一切都很好
//但是如果我离开这个,UI就会冻结!!
GetPictureAsync();
base.InitLayout();
}
/// 
/// 
/// 
私有void GetPictureAsync()
{
//这一行需要发生在UI线程上。。。
TaskScheduler uiScheduler=TaskScheduler.FromCurrentSynchronizationContext();
Task.Factory.StartNew(()=>
{
随机睡眠=新的随机睡眠();
系统线程线程睡眠(Sleep.Next(10003000));
if(this.pbPhoto.invokererequired)
{
this.pbPhoto.Invoke(新操作(()=>
{
加载(@“E:\Photos\”+PhotoId.ToString()+“.jpg”);
//this.pbPhoto.Image=Utility.Common.GetResourceImage(“woman_sample.jpg”);
}));
}
其他的
{
加载(@“E:\Photos\”+PhotoId.ToString()+“.jpg”);
//this.pbPhoto.Image=Utility.Common.GetResourceImage(“woman_sample.jpg”);
}
},CancellationToken.None,TaskCreationOptions.None,uiScheduler);
}
所以问题似乎是,我首先执行一个线程来查找何时开始搜索,然后在该线程内运行另一个线程以从数据库获取数据,然后UI中更新的每个控件将运行另一个线程以获取图片并更新picturebox

有人知道怎么解决这个问题吗?还是解决这个问题的方法?

当您打电话时

new CustomControls.Controls.PersonResult("123", "123", index + 150)
“123”是一个文本字符串,或者它们是从UI控件读取的。比如说,

new CustomControls.Controls.PersonResult(txtFathersName.Text", txtMothersName.Text, index + 150)

我现在无法测试它,但是不允许从创建控件的线程以外的线程访问Text属性吗?

我认为问题在于您强制在UI线程上执行
GetPictureAsync
中的任务,然后调用
thread.Sleep()
。这个问题和你现在遇到的问题是一样的。我会将您的代码改写为:

private void async GetPictureAsync()
{
    Random sleep = new Random();
    await TaskEx.Delay(sleep.Next(1000,3000));
    this.Load(@"E:\Photos\" + PhotoId.ToString() + ".jpg");
}