C# 计时器和任务是否正在创建新线程?
在我的应用程序中,当单击C# 计时器和任务是否正在创建新线程?,c#,wpf,multithreading,asynchronous,task,C#,Wpf,Multithreading,Asynchronous,Task,在我的应用程序中,当单击按钮时,会触发命令,下载图像(我希望是异步的)和字符串,名称和字符,如下所述。下载这些项目的函数从Dispatchermer调用,如下所示: timer.Tick += myMethodToDownloadCastInfo; 在这种方法中,我有: timer.Stop(); List<CastWithPic> castWithPicList = new List<CastWithPic>(); // Add name and id for
按钮时,会触发命令,下载图像(我希望是异步的)和字符串,名称和字符,如下所述。下载这些项目的函数从Dispatchermer
调用,如下所示:
timer.Tick += myMethodToDownloadCastInfo;
在这种方法中,我有:
timer.Stop();
List<CastWithPic> castWithPicList = new List<CastWithPic>();
// Add name and id for each CastWithPic in the list
// ..
_viewModel.SelectedItem.castInfoWithPics = castWithPicList;
// Download all the required pics
var tasks = new List<Task>();
foreach (CastWithPic cast in castWithPicList)
{
tasks.Add(downloadBitmap(cast.profilePath, cast.id));
}
await Task.WhenAll(tasks);
SelectedItem
在myViewModel
中声明
SelectedItem
Class
public List<CastWithPic> castInfoWithPics { get; set; }
public string name
{
get { return (string)this.GetValue(nameProperty); }
set
{
this.SetValue(nameProperty, value);
}
}
public static readonly DependencyProperty nameProperty = DependencyProperty.Register(
"name", typeof(string),
typeof(CastWithPic));
public string character
{
get { return (string)this.GetValue(characterProperty); }
set
{
this.SetValue(characterProperty, value);
}
}
public static readonly DependencyProperty characterProperty = DependencyProperty.Register(
"character", typeof(string),
typeof(CastWithPic));
public Bitmap image
{
get { return (Bitmap)this.GetValue(imageProperty); }
set
{
this.SetValue(imageProperty, value);
}
}
public static readonly DependencyProperty imageProperty = DependencyProperty.Register(
"image", typeof(Bitmap),
typeof(CastWithPic));
下载位图
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
RequestState myRequestState = new RequestState();
myRequestState.request = request;
// Start the asynchronous request.
IAsyncResult result = request.BeginGetResponse(new AsyncCallback(RespCallback), Tuple.Create(myRequestState, actorID));
// this line implements the timeout, if there is a timeout, the callback fires and the request becomes aborted
ThreadPool.RegisterWaitForSingleObject(result.AsyncWaitHandle, new WaitOrTimerCallback(TimeoutCallback), request, DefaultTimeout, true);
// The response came in the allowed time. The work processing will happen in the
// callback function.
allDone.WaitOne();
我的问题是:
为什么分配时不出现错误,\u viewModel.SelectedItem.castInfoWithPics=castWithPicList在定时器
方法中使用code>,但在任务
方法中出现错误
计时器
是否也在启动一个新的线程
在这种情况下,使用此处建议的解决方案是否是解决问题的正确方法
您必须冻结对象,问题就解决了。
以下是一个示例:
videoIcon = new BitmapImage();
videoIcon.BeginInit();
videoIcon.UriSource = new Uri(@"C:\Data\Image1.jpg");
videoIcon.DecodePixelWidth = 14;
videoIcon.EndInit();
videoIcon.Freeze();
在没有冻结()的情况下,我收到了与您相同的错误消息。使用Freeze()解决问题。
更多信息请点击此处:
“冻结的Freezable也可以跨线程共享,而未冻结的Freezable则不能。”我认为需要在UI线程中设置\u viewModel.SelectedItem.castInfoWithPics=castWithPicList
。您的donloadBitmap
函数使用回调来处理响应,该回调在ThreadPool
线程上运行
您可以使用Dispatcher.Invoke
强制在UI线程上执行工作。尝试将其放入回调中,并将适当的代码放入注释部分:
Application.Current.Dispatcher.BeginInvoke(
DispatcherPriority.Background,
new Action(() => /* set selected item */));
要获得更好的解决方案,您可以使用async wait
,它可以恢复当前的synchronizationcontext
,并且您不需要使用Dispatcher.Invoke
HttpClient
提供了一个可以使用的异步友好API
下面是一个设置文本框值的简单示例
private async Task DownloadUrlAsync(string url)
{
using (HttpClient httpClient = new HttpClient())
{
textBox1.Text = await httpClient.GetStringAsync(url);
}
}
你的下载位图
函数是什么样子的?嗨@NedStoyanov,我添加了下载位图
功能。你在哪里设置SelectedItem
它是RspCallback
?@NedStoyanovSelectedItem
是在我的视图模型
中设置的。我认为这与OP的问题无关。罗伯特·哈维,你似乎是个出口,也许你是对的。但我也遇到了类似的问题,经过大量的研究,我找到了适合我的Freeze()解决方案。也许Giri可以尝试冻结图像,让我们知道这是否解决了问题。这是一个很好的猜测。很难说OP什么时候没有提供必要的细节,比如他正在使用哪个定时器对象或者错误消息是什么。
private async Task DownloadUrlAsync(string url)
{
using (HttpClient httpClient = new HttpClient())
{
textBox1.Text = await httpClient.GetStringAsync(url);
}
}