C# 创建的线程不与主C同步运行#
我已经创建了一个线程,但该线程在我启动主进程后暂停。该线程从google加载一些图像,但当internet连接断开时,用户界面将无法使用 这是线程:C# 创建的线程不与主C同步运行#,c#,wpf,multithreading,C#,Wpf,Multithreading,我已经创建了一个线程,但该线程在我启动主进程后暂停。该线程从google加载一些图像,但当internet连接断开时,用户界面将无法使用 这是线程: string searchWord = "car photo"; PhotoSearchThread = new Thread(() => { Thread.CurrentThread.IsBackground = true; if (!string.IsNullOrWhiteSpace(searchWord)) {
string searchWord = "car photo";
PhotoSearchThread = new Thread(() =>
{
Thread.CurrentThread.IsBackground = true;
if (!string.IsNullOrWhiteSpace(searchWord))
{
string html = GetHtmlCode(searchWord);
SearchedImagesUrls = GetUrls(html);
this.Dispatcher.Invoke(() =>
{
if (SearchedImagesUrls.Count > 0)
{
BitmapImage image = new BitmapImage();
image.BeginInit();
image.CacheOption = BitmapCacheOption.OnLoad;
image.UriSource = new Uri(SearchedImagesUrls[0]);
image.EndInit();
SelectPhotoImage.Source = image;
}
});
}
});
PhotoSearchThread.Start();
那么线程应该同时运行,那么为什么这个线程会中断其他线程呢
Invoke
用于在主线程或UI线程上运行代码。专门用于更新UI元素,因为这些元素只能由该线程更新。当前,您有在调用中加载图像的代码。相反,您应该只将更新UI的部分代码放在调用
中
PhotoSearchThread = new Thread(() =>
{
Thread.CurrentThread.IsBackground = true;
if (!string.IsNullOrWhiteSpace(searchWord))
{
string html = GetHtmlCode(searchWord);
SearchedImagesUrls = GetUrls(html);
if (SearchedImagesUrls.Count > 0)
{
BitmapImage image = new BitmapImage();
image.BeginInit();
image.CacheOption = BitmapCacheOption.OnLoad;
image.UriSource = new Uri(SearchedImagesUrls[0]);
image.EndInit();
this.Dispatcher.Invoke(() =>
{
SelectPhotoImage.Source = image;
});
}
}
});
Invoke
用于在主线程或UI线程上运行代码。专门用于更新UI元素,因为这些元素只能由该线程更新。当前,您有在调用中加载图像的代码。相反,您应该只将更新UI的部分代码放在调用
中
PhotoSearchThread = new Thread(() =>
{
Thread.CurrentThread.IsBackground = true;
if (!string.IsNullOrWhiteSpace(searchWord))
{
string html = GetHtmlCode(searchWord);
SearchedImagesUrls = GetUrls(html);
if (SearchedImagesUrls.Count > 0)
{
BitmapImage image = new BitmapImage();
image.BeginInit();
image.CacheOption = BitmapCacheOption.OnLoad;
image.UriSource = new Uri(SearchedImagesUrls[0]);
image.EndInit();
this.Dispatcher.Invoke(() =>
{
SelectPhotoImage.Source = image;
});
}
}
});
我找到了解决办法:
1.添加以下用法:使用System.ComponentModel代码>
2.申报背景工人:
3.订阅活动:
4.实施两种方法:
5.根据需要随时运行worker async
另外,如果您想报告流程进度,您应该订阅ProgressChanged事件,并在DoWork方法中使用ReportProgress(Int32)
来引发事件。还设置以下内容:worker.WorkerReportsProgress=true代码>(感谢@zagy)
资料来源:
希望对您有所帮助。我找到了解决方案:
1.添加以下用法:使用System.ComponentModel代码>
2.申报背景工人:
3.订阅活动:
4.实施两种方法:
5.根据需要随时运行worker async
另外,如果您想报告流程进度,您应该订阅ProgressChanged事件,并在DoWork方法中使用ReportProgress(Int32)
来引发事件。还设置以下内容:worker.WorkerReportsProgress=true代码>(感谢@zagy)
资料来源:
希望有帮助。您确实意识到,调用
告诉它在主线程上运行该代码。我猜SelectPhotoImage.Source=image
是唯一需要在调用中的部分。啊哈,我不知道。谢谢你的回答。但是,有没有办法将它们分开,同时更改图像源?只需将除赋值之外的所有内容都放在调用之外?谢谢你的回答Jeroen。我担心图像加载函数花费的时间比它应该花费的时间长,并且图像分配将无法工作,因为链接数组尚未就绪…您确实意识到,调用
正在告诉它在主线程上运行该代码。我猜SelectPhotoImage.Source=image
是唯一需要在调用中的部分。啊哈,我不知道。谢谢你的回答。但是,有没有办法将它们分开,同时更改图像源?只需将除赋值之外的所有内容都放在调用之外?谢谢你的回答Jeroen。我担心图像加载功能花费的时间比它应该花费的时间长,并且图像分配将无法工作,因为链接数组尚未就绪。。。
worker.DoWork += worker_DoWork;
worker.RunWorkerCompleted += worker_RunWorkerCompleted;
private void worker_DoWork(object sender, DoWorkEventArgs e)
{
// run all background tasks here
}
private void worker_RunWorkerCompleted(object sender,
RunWorkerCompletedEventArgs e)
{
//update ui once worker complete his work
}
worker.RunWorkerAsync();