在我的windows phone 8.1應用程序中,我有一個單例服務DataService,它應該偶爾下載一些數據。同時在UI上,我應該顯示收到的數據量。 DataService.StartGettingData()被調用時,用戶登錄到應用程序:該應用程序稱爲一個接口,該接口被編組爲另一個線程。 (來自HRESULT的異常:0x8001010E(RPC_E_WRONG_THREAD))
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);
}
}
當用戶註銷與
if (getDataTaskCancellationTokenSource != null)
getDataTaskCancellationTokenSource.Cancel();
幫助包含的下載貌似結果的屬性該任務將被取消這個:
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);
}
這部分似乎工作,直到我必須顯示屏幕上的數據量。 我的MainViewModel獲取注入Ninject的DataService的實例。
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();
}
在XAML我已經得到的TextBlock綁定到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));
}
}
的DATACOUNT財產,這裏是哪裏的問題出現:OnPropertyChanged失敗, 「的應用程序調用這是整理爲不同的接口線程(來自HRESULT的異常:0x8001010E(RPC_E_WRONG_THREAD))「,它被DataService.LoadDataAsync()捕獲。 我知道運行時正試圖告訴我,我正在從非UI線程訪問UI元素。但我呢?我認爲OnPropertyChanged是將UI與其他後臺任務斷開的神奇之處。 當然,這個問題是可以解決的實施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()中丟失了什麼?
您在哪裏創建視圖模型的新實例,以及它如何與您的xaml連接? – 2014-11-24 16:48:35
您是否在單獨的線程中運行取決於從哪裏調用OnDataUpdated。我懷疑它是在LoadDataAsync方法中,如果是的話,那麼是的,它是在一個單獨的線程中。沒有什麼魔法可以使用戶界面線程可以證明,所以你的方法是正確的。 – Kell 2014-11-24 16:52:56
@Kell,OnDataUpdated在IEnumerable內部調用數據,所以我猜想它正在後臺線程上運行。 –
foxanna
2014-11-24 20:38:33