为了账号安全,请及时绑定邮箱和手机立即绑定

foreach 内的“跨线程操作无效”

foreach 内的“跨线程操作无效”

C#
哆啦的时光机 2023-09-09 16:50:26
我正在尝试将数据加载到组合框,并且当我运行表单而不进行调试时它正在工作。但是,当我尝试使用调试模式运行它时,出现错误:System.InvalidOperationException:“跨线程操作无效:从创建它的线程以外的线程访问控制“ResultBox”。” 我怎样才能解决这个问题?顺便说一句,有一个后台工作人员在下载数据时写入消息。我在某处读到可以使用后台工作人员解决此问题。这是表单代码: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;    }}
查看完整描述

1 回答

?
繁华开满天机

TA贡献1816条经验 获得超4个赞

如果采用异步,则始终采用异步。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 控件时,可以在创建它们的主线程上访问它们(请参阅注释)。


查看完整回答
反对 回复 2023-09-09
  • 1 回答
  • 0 关注
  • 57 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信