我正在尝试将数据加载到组合框,并且在我运行表单而不进行调试时它就可以正常工作。但是,当我尝试在调试模式下运行它时,出现错误:System.InvalidOperationException:“跨线程操作无效:控制'ResultBox'从不是在其上创建线程的线程访问。 我怎样才能解决这个问题?而且顺便说一句,有一个后台工作人员在下载数据时会写消息。我在某处读到可以使用backgroundworker修复此问题。这是表单代码:
public Form1()
{
InitializeComponent();
backgroundWorker1.WorkerReportsProgress = true;
}
private void Form1_Load(object sender, EventArgs e)
{
backgroundWorker1.RunWorkerAsync();
}
private Task GetDataTask() {
return Task.Factory.StartNew(() => {
List<Result> results = new List<Result>();
results =
GetResults.GetData("http://worldcup.sfg.io/teams/results/");
foreach (var result in results)
{
ResultBox.Items.Add(result.Fifa_Code);
}
});
}
private void ResultBox_SelectedIndexChanged(object sender, EventArgs e)
{
}
private void SaveTeam_Click(object sender, EventArgs e)
{
}
private async void backgroundWorker1_DoWork(object sender,
DoWorkEventArgs e)
{
await GetDataTask();
}
private void backgroundWorker1_ProgressChanged(object sender,
ProgressChangedEventArgs e)
{
resultsLoadedLabel.Text = (e.ProgressPercentage.ToString() + "%");
}
private void backgroundWorker1_RunWorkerCompleted(object sender,
RunWorkerCompletedEventArgs e)
{
resultsLoadedLabel.Text = "Podaci učitani!";
}
foreach内的这行代码获取异常:
ResultBox.Items.Add(result.Fifa_Code);
这是获取结果的类:
public class GetResults
{
public static List<Result> GetData(string url) {
var client = new RestClient();
var request = new RestRequest(url, Method.GET);
request.AddHeader("User-Agent", "Nothing");
IRestResponse<List<Result>> results = client.Execute<List<Result>>
(request);
return results.Data;
}
}
答案 0 :(得分:2)
如果要异步,则要一直异步。 RestSharp允许您进行异步调用
因此您可以重构对的数据访问
public class GetResults {
public static async Task<List<Result>> GetDataAsync(string url) {
var client = new RestClient();
var request = new RestRequest(url, Method.GET);
request.AddHeader("User-Agent", "Nothing");
IRestResponse<List<Result>> results = await client.ExecuteTaskAsync<List<Result>>(request);
return results.Data;
}
}
接下来,由于表单加载是事件处理程序,因此您也可以使该异步并加载数据。
public Form1() {
InitializeComponent();
}
private async void Form1_Load(object sender, EventArgs e) {
//On UI thread
resultsLoadedLabel.Text = "Loading data!";
//get data on separate thread (non blocking)
List<Result> results = await GetResults.GetDataAsync("http://worldcup.sfg.io/teams/results/");
//Back on UI thread
resultsLoadedLabel.Text = "Podaci učitani!";
foreach (var result in results) {
ResultBox.Items.Add(result.Fifa_Code);
}
}
确保在使用异步调用时访问UI控件时,可以在创建它们的主线程上访问它们,(请参见注释)。