An application is called an interface that has been configured for another thread. (Exception from HRESULT: 0x8001010E (RPC_E_WRONG_THREAD))

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()?

+4
1

, , :

Task.Factory.StartNew(async () => await ExecuteCycleAsync(token), token);

, , :

ExecuteCycleAsync(token);

ExecuteCycleAsync , , , LoadDataAsync.

, ExecuteCycleAsync(token), , - " ", ( ). Task, .

+7

All Articles