问题描述
我有以下代码将查询发送到youtube,并将总结果发送到文本框。如果我只是警告结果,可以,但是我无法将结果分配给文本框。请向我解释为什么?
I have the following code to send a query to youtube and send the total result to a textbox. If I just alert the result, it's OK but I can't assign the result to a textbox. Please explain to me why?
private void SearchVideo(string keyword)
{
string orderBy = "";
switch (cboSortBy.SelectedIndex)
{
case 1: orderBy = "published"; break;
case 2: orderBy = "viewCount"; break;
case 3: orderBy = "rating"; break;
default: orderBy = "relevance"; break;
}
SearchDelegate sd = Search;
sd.BeginInvoke(keyword, orderBy, SearchCompleted, sd);
}
private void SearchCompleted(IAsyncResult ar)
{
if (null == ar) return;
SearchDelegate sd = ar.AsyncState as SearchDelegate;
Feed<Video> result = sd.EndInvoke(ar);
txtSearch.Text = result.TotalResults.ToString();
}
private Feed<Video> Search(string keyword, string orderBy)
{
YouTubeQuery query = new YouTubeQuery(YouTubeQuery.DefaultVideoUri);
query.OrderBy = orderBy;
query.Query = keyword;
query.SafeSearch = YouTubeQuery.SafeSearchValues.None;
return GetRequest().Get<Video>(query);
}
和错误
跨线程操作无效:
从
线程(而不是在其上创建
的线程)访问'txtSearch'。
推荐答案
您正在呼叫 BeginInvoke
,因此您的代表是在线程池线程上被调用。您无法从该线程池线程访问用户界面;您需要在控件上调用 Invoke
或 BeginInvoke
,然后在UI线程上使用结果。例如,使用匿名方法:
You're calling BeginInvoke
so your delegate is being invoked on a thread-pool thread. You can't access the UI from that thread-pool thread; you need to call Invoke
or BeginInvoke
on the control to then use the results on the UI thread. For instance, using an anonymous method:
txtSearch.BeginInvoke((MethodInvoker) delegate()
{ txtSearch.Text = result.TotalResults.ToString(); }
);
或者使用lambda表达式,并且为了清楚起见使用单独的局部变量:
Or using a lambda expression, and with a separate local variable just for clarity:
MethodInvoker action= () => { txtSearch.Text = result.TotalResults.ToString();};
txtSearch.BeginInvoke(action);
使用 Invoke
将使调用线程阻塞直到UI线程调用了委托为止; BeginInvoke
是非阻塞的。
Using Invoke
will make the calling thread block until the UI thread has invoked the delegate; BeginInvoke
is non-blocking.
编辑:如果问题是 result.TotalResults
是需要很长时间的位,还是在后台线程上执行该位:
If the problem is that result.TotalResults
is the bit that takes a long time, do that bit still on the background thread:
string text = result.TotalResults.ToString();
txtSearch.BeginInvoke((MethodInvoker) delegate() { txtSearch.Text = text; });
这篇关于.NET中BeginInvoke的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!