In my app, when a Button
is clicked a Command
is triggered that downloads the image
(asynchronously.. I hope) and the strings
, name
and character
, specified below. The function to download these items is called from a DispatcherTimer
as such:
timer.Tick += myMethodToDownloadCastInfo;
Within this method I have:
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);
Within the downloadBitmap
function I set the object SelectedItem's
castInfoWithPics
to hold the image
value.
It is at this point that I am receiving the error:
The calling thread cannot access this object because a different thread owns it.
SelectedItem
is declared in my ViewModel
.
SelectedItem
Class
public List<CastWithPic> castInfoWithPics { get; set; }
CastWithPic
Class
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));
downloadBitmap
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();
My question is:
Why don't I get an error when I assign, _viewModel.SelectedItem.castInfoWithPics = castWithPicList;
in the timer
method but I get an error in the Task
method.
Isn't the timer
also starting a new thread
?
In this case is the proper way to resolve the issue to use the solution suggested here?
The calling thread cannot access this object because a different thread owns it