c# - 如何使用富文本框的等待和异步?
问题描述
我试图制作一个应用程序来检查 ebay 当前的观察者。我使用以下代码查找 ebay 观察者计数.. 它很好。然后我使用等待异步代码来修复 UI 阻塞..
但它正在变得无效操作异常是未处理的异常。
private async void button1_Click(object sender, EventArgs e)
{
Task<int> task = new Task<int>(counting);
task.Start();
label1.Text = "Please wait";
await task;
}
private int counting()
{
string[] idlist = richTextBox1.Text.Split('\n'); // <= getting exception
// foreach (string id in idlist)
for (int i = 0; i < Convert.ToInt32(idlist.Length); i++)
{
string url = "http://m.ebay.com/itm/" + idlist[i];
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
StreamReader sr = new StreamReader(response.GetResponseStream());
// richTextBox2.Text += sr.ReadToEnd();
string a = sr.ReadToEnd();
sr.Close();
string number = String.Empty;
string pattern = @"(?<=""defaultWatchCount""\s*:\s*)\d+";
string input = a;
foreach (Match m in Regex.Matches(input, pattern))
{
number = m.Value;
}
richTextBox2.Text += number + Environment.NewLine;
}
return 0;
}
我对等待和异步知之甚少......有人可以解决这个错误吗?
解决方案
尝试从与创建它的线程不同的线程访问 UI 控件将导致跨线程访问冲突。因此,如果目标是在后台线程上进行 Web 调用,那么您需要将后台任务与 UI 分开
以下是对原始代码的重构,该代码采用一组 id 并HttpClient
用于进行异步 Web 调用。所有的网络调用都将在不同的线程上并行完成。
static Lazy<HttpClient> client = new Lazy<HttpClient>(() => {
string baseUrl = "http://m.ebay.com/itm/";
var client = new HttpClient() {
BaseAddress = new Uri(baseUrl)
};
return client;
});
private Task<string[]> GetWatchCountsAsync(string[] idlist) {
string pattern = @"(?<=""defaultWatchCount""\s*:\s*)\d+";
var tasks = idlist.Select(async id => {
var input = await client.Value.GetStringAsync(id.Trim());
string number = String.Empty;
foreach (Match m in Regex.Matches(input, pattern)) {
number += m.Value;
}
return number;
});
return Task.WhenAll(tasks);
}
所以现在在按钮单击处理程序中,您从 UI 线程开始,将请求卸载到其他线程并等待它们完成,同时不锁定 UI 线程。完成后,您提取返回的值并根据需要传递它们
private async void button1_Click(object sender, EventArgs e) {
label1.Text = "Please wait..."; //UI Thread
var idlist = richTextBox1.Text.Split('\n'); //UI Thread
var numbers = await GetWatchCountsAsync(idlist); //background thread(s) (non-blocking)
richTextBox2.Text += string.Join(Environment.NewLine, numbers); // Back on UI thread
label1.Text = "Done"; //UI Thread
}
推荐阅读
- mybatis - Mybatis查询bigInteger报错
- c++ - OpenMP - 并行和嵌套循环
- javascript - Express/Mongoose 仅将部分请求数据保存到数据库
- php - 二叉树,如何计算所有左右子 php,mysql
- vb.net - VB.Net 和 phpMyAdmin:如何在不需要用户名或密码的情况下连接到 phpMyAdmin SQL 服务器?
- angular - 如何解决 .js.map 在控制台中引发错误。添加地图文件后
- navision - 错误销售发票行不退出
- wordpress - Wordpress .htaccess 重定向问题
- associations - CakePHP3:在行为中添加关联
- web-services - Sitefinity REST/oData 使用类别和标签创建图像