我试图制作一个应用来检查eBay当前的观察者。我使用以下代码找到eBay观察者计数..没问题。然后我使用await asyncro代码修复UI阻塞。
但它正在获取invalidoperationexception是未处理的异常。
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;
}
我对等待和异步了解不多...请问有人可以解决此错误吗?
答案 0 :(得分:0)
尝试从与创建线程不同的线程访问UI控件将导致跨线程访问冲突。因此,如果目标是在后台线程上进行网络调用,那么您需要将后台任务与用户界面分开
以下是对原始代码的重构,该原始代码采用ID集合并使用ngOnChanges(changes: SimpleChanges) {
this.C_code = this.CartdataService.category_code;
this.G_code = this.CartdataService.group_code;
this.SG_code = this.CartdataService.subgroup_code;
this.CartdataService.get_Selected_Category_Of_Products(this.C_code,
this.G_code, this.SG_code).subscribe(
(data : any) => {
this.size = data.length;
this.CartdataService.prooductCountUnderCGS.next(this.size);
this.products = data;
});
}
进行异步Web调用。所有Web调用将在单独的线程上并行完成。
HttpClient
因此,现在在按钮单击处理程序中,您可以在UI线程中启动,将请求卸载到其他线程,并等待它们完成,同时不锁定UI线程。完成后,您将提取返回的值,并根据需要将其传递给
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);
}