.NET中BeginInvoke的问题 [英] Problem with BeginInvoke in .NET

查看:188
本文介绍了.NET中BeginInvoke的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下代码将查询发送到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'。

Cross-thread operation not valid: Control 'txtSearch' accessed from a thread other than the thread it was created on.


推荐答案

您正在呼叫 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的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆