In my Windows phone 8.1 application, I have a Singleton DataService service that needs to download some data from time to time. Meanwhile, in the user interface, I have to display the amount of data received. DataService.StartGettingData () is called when a user logs into the application:
void StartGettingData()
{
if (getDataTaskCancellationTokenSource != null)
getDataTaskCancellationTokenSource.Cancel();
getDataTaskCancellationTokenSource = new CancellationTokenSource();
var token = getDataTaskCancellationTokenSource.Token;
Task.Factory.StartNew(async () => await ExecuteCycleAsync(token), token);
}
async Task ExecuteCycleAsync(CancellationToken cancellationToken)
{
while (true)
{
cancellationToken.ThrowIfCancellationRequested();
await LoadDataAsync(cancellationToken);
cancellationToken.ThrowIfCancellationRequested();
await Task.Delay(timeTillNextDownload, cancellationToken);
}
}
This task will be canceled when the user logs out using
if (getDataTaskCancellationTokenSource != null)
getDataTaskCancellationTokenSource.Cancel();
The property containing the load result is as follows:
List<DataType> Data = new List<DataType>();
public IEnumerable<DataType> Data
{
get { return Data; }
set
{
Data = value.ToList();
OnDataUpdated();
}
}
void OnDataUpdated()
{
var handler = DataUpdated;
if (handler != null)
handler(this, EventArgs.Empty);
}
This part seemed to work until I had to display the amount of data on the screen. My MainViewModel gets an instance of a DataService injected using Ninject.
readonly IDataService DataService;
public MainViewModel(IDataService dataService)
{
DataService = dataService;
DataService.DataUpdated += DataService_DataUpdated;
UpdateDataCount();
}
void DataService_DataUpdated(object sender, EventArgs e)
{
UpdateDataCount();
}
void UpdateDataCount()
{
DataCount = DataService.Data.Count();
}
In xaml, I have a TextBlock bound to the DataCount property of MainViewModel
int DataCount;
public int DataCount
{
get { return DataCount; }
set
{
DataCount = value;
OnPropertyChanged();
}
}
protected void OnPropertyChanged([CallerMemberName] string propertyName = "")
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
: OnPropertyChanged
" , . ( HRESULT: 0x8001010E (RPC_E_WRONG_THREAD))", DataService.LoadDataAsync().
, , non ui. ? , OnPropertyChanged - , .
, OnPropertyChanged :
public CoreDispatcher Dispatcher { get; set; }
protected async void OnPropertyChanged([CallerMemberName] string propertyName = "")
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
{
handler(this, new PropertyChangedEventArgs(propertyName));
});
}
}
? - DataService.ExecuteCycleAsync()?