gpt4 book ai didi

c# - 事件中控件文本更新抛出非法跨线程异常

转载 作者:太空宇宙 更新时间:2023-11-03 23:03:53 25 4
gpt4 key购买 nike

我正在以编程方式通过关键字进行 Youtube 搜索,并使用 Youtube API 来执行此操作。我想在搜索进度完成时触发一个事件,并在 YoutubeSearchCompleted 发送的 YoutubeSearchCompletedEventArgs 中返回结果。

但是Form.csYoutubeSearchCompleted中的代码抛出跨线程非法操作异常。通常,使用 AsyncOperation.Post 方法时不得抛出 InvalidOperationException。因为我之前在一个下载管理器项目中用过同样的方法,效果很好。所以我不明白为什么会这样。

Youtube search class

class YouTubeManager
{
public delegate void YoutubeSearchCompletedEventHandler(object sender, YoutubeSearchCompletedEventArgs e);
public event YoutubeSearchCompletedEventHandler YoutubeSearchCompleted;
AsyncOperation aop = AsyncOperationManager.CreateOperation(null);

List<YoutubeVideo> SearchByKeyword(string keyword)
{
List<YoutubeVideo> videos = new List<YoutubeVideo>();

//.......
//...Youtube data api search codes....
//.......

return videos;
}
public void Search(string keyword)
{
Task.Run(() =>
{
List<YoutubeVideo> list = SearchByKeyword(keyword);
aop.Post(new System.Threading.SendOrPostCallback(delegate
{
if (YoutubeSearchCompleted != null)
YoutubeSearchCompleted(this,
new YoutubeSearchCompletedEventArgs(keyword, list);
}), null);
});
}
}

Form.cs

public partial class Form1 : Form
{
YouTubeManager yam = new YouTubeManager();
public Form1()
{
InitializeComponent();
this.Load += Form1_Load;
}

void Form1_Load(object sender, EventArgs e)
{
yam.YoutubeSearchCompleted += yam_YoutubeSearchCompleted;
yam.Search("Blues");
}

void yam_YoutubeSearchCompleted(object sender, YoutubeSearchCompletedEventArgs e)
{
if (e.Videos.Count < 1) return;

textBox1.Text = e.Videos[0].Title();
}
}

在此代码中,textBox1.Text = e.Videos[0].Title(); 行抛出 InvalidOperationException。我该如何解决这个问题?

注意:我不需要Invoke方法,只需要AsyncOperation

最佳答案

问题很可能是由过早创建的 AsyncOperation 引起的。您可以通过以下方式进行检查:

if (!(aop.SynchronizationContext is WindowsFormsSynchronizationContext))
{
// Oops - we have an issue
}

这是为什么呢? AsyncOperation 存储 SynchronizationContext.Current在构造时,通常所有 Control 派生类(包括 Form)都从 Control 内部安装 WindowsFormsSynchronizationContext类构造函数。

但假设 Forgm1 是您的启动表单(例如典型的 Application.Run(new Form1()); 来自 Main 的调用) .自 Any instance variable initializers in the derived class are executed before the base class constructor ,在 aop 变量初始化时(通过 yam 字段初始化器),Control 类构造函数尚未运行,因此 WindowsFormsSynchronizationContext 未安装,因此 AsynOperation 使用默认的 SynchronozationContext 初始化,它通过简单地在单独的执行它来实现 Post线程。

修复很简单 - 不要使用初始化器,只需定义字段

YouTubeManager yam;

并移动初始化

yam = new YouTubeManager();

在表单构造函数或加载事件中。

关于c# - 事件中控件文本更新抛出非法跨线程异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42054737/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com