同时读取数据GUI没有响应 [英] GUI not responding while fetching data

查看:121
本文介绍了同时读取数据GUI没有响应的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的应用往往取使用的WebRequest网页数据,但它不可能点击按钮等,而它的提取。我明白,我必须使用线程/一个BackgroundWorker,但我不能让它正常工作;它不会使图形用户界面更能够响应。

My application often fetch data from a webpage using WebRequest, but it isn't possible to click buttons etc while it's fetching. I've understood that I have to use threads/a backgroundworker, but I can't get it to work properly; it doesn't make the GUI more respondable.

我想申请某种线程上,使其停止让我的应用程序不能响应代码:

The code I want to apply some kind of threading on, so that it stops making my application unresponding:

public string SQLGet(string query)
{
    string post = "q=" + query;
    WebRequest request = WebRequest.Create("http://test.com");
    request.Timeout = 20000;
    request.Method = "POST";
    byte[] bytes = Encoding.UTF8.GetBytes(post);
    request.ContentType = "application/x-www-form-urlencoded";
    request.ContentLength = bytes.Length;

    Stream requestStream = request.GetRequestStream();
    requestStream.Write(bytes, 0, bytes.Length);
    requestStream.Close();

    WebResponse response = request.GetResponse();
    requestStream = response.GetResponseStream();
    StreamReader reader = new StreamReader(requestStream);
    string ret = reader.ReadToEnd();

    reader.Close();
    requestStream.Close();
    response.Close();

    return ret;
}





编辑:谢谢您,立法会,我试过很相似的东西。但我的问题与使用BackgroundWorker喜欢就是;我怎么了QueryResult中返回到其调用函数(在我的情况SQLGet,和你的情况)StartQuery?

Thank you, lc, I had tried something pretty similar to that. But my problem with using the backgroundworker like that is; how do I get the queryResult back to the function which called (in my case SQLGet, and in your case) StartQuery?

在我的例子中,返回的字符串是要用作局部变量在空隙的串内被调用。

In my example, the returned string is going to be used as a local variable in the void the string is called inside.

和可能在同一时间有很多疑问,所以我不想冒险将其分配给一个全局变量。

And there may be many queries at the same time, so I don't want to risk assigning it to a global variable.

推荐答案

下面是一个如何使用的 的BackgroundWorker 因为它适用于您的代码:

Here's a simple example of how to use the BackgroundWorker as it applies to your code:

private void StartQuery(string query)
{
    BackgroundWorker backgroundWorker1 = new BackgroundWorker();
    backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);
    backgroundWorker1.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted);
    backgroundWorker1.RunWorkerAsync(query);
}

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{   
    e.Result = SQLGet((string)e.Argument);
}

private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    queryResult = (string)e.Result;
}

您可能还希望允许取消,提供错误的详细信息,或提供可靠的反馈因为它获取数据。看看这个例子 href=\"http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx\" rel=\"nofollow\">更多详情。

You may also wish to allow cancellation, provide error details, or provide robust feedback as it fetches data. Take a look at the example on the MSDN page for more details.

您的查询将在 BackgroundWorker.RunWorkerCompleted 事件作为显示的结果 e.Result (我保存它作为在这种情况下,一个实例变量)。如果你要在同一时间运行许多这些,你需要一个方法来区分哪个查询是哪个。所以,你应该通过不只是一个字符串的方法多。拿这个例子:

The result of your query will show up in the BackgroundWorker.RunWorkerCompleted event as e.Result (I've stored it as an instance variable in this case). If you're going to run many of these at the same time, you'll need a way to differentiate which query is which. So you should pass more than just a string to the method. Take this example:

private int NextID = 0;

private struct QueryArguments
{
    public QueryArguments()
    {
    }

    public QueryArguments(int QueryID, string Query)
        : this()
    {
        this.QueryID = QueryID;
        this.Query = Query;
    }

    public int QueryID { get; set; }
    public string Query { get; set; }
    public string Result { get; set; }
}

private int StartQuery(string query)
{
    QueryArguments args = new QueryArguments(NextID++, query);

    BackgroundWorker backgroundWorker1 = new BackgroundWorker();
    backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);
    backgroundWorker1.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted);
    backgroundWorker1.RunWorkerAsync(args);

    return args.QueryID;
}

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{   
    QueryArguments args = (QueryArguments)e.Argument;
    args.Result = SQLGet(args.Query);
    e.Result = args;
}

private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    QueryArguments args = (QueryArguments)e.Result;
    //args.Result contains the result

    //do something
}

这篇关于同时读取数据GUI没有响应的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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