我注意到這裏有一些很奇怪的東西。將權限/身份驗證複製到子線程...?
我正在編寫一個CRM 2011 Silverlight擴展,當然,在我的本地開發實例中,這一切都很好。應用程序使用OData進行通信,並且使用System.Threading.Tasks.Task
大量地執行後臺中的所有操作(FromAsync
是祝福)。但是,我決定在CRM 2011 Online中測試我的應用程序,發現令我驚訝的是,它不再有效;結束檢索任務時,我會收到安全異常。
使用招,我發現,CRM試圖給我重定向到Live登錄頁面,這並沒有太大的意義,考慮到我已經登錄。
一些更多的嘗試之後,我發現,錯誤是因爲我從不同於UI線程的線程訪問服務。
這裏有一個簡單的例子:
//this will work
private void button1_Click(object sender, RoutedEventArgs e)
{
var query = ctx.AccountSet;
query.BeginExecute((result) =>
{
textBox1.Text = query.EndExecute(result).First().Name;
}, null);
}
//this will fail
private void button2_Click(object sender, RoutedEventArgs e)
{
System.Threading.Tasks.Task.Factory.StartNew(RestAsync);
}
void RestAsync()
{
var query = ctx.AccountSet;
var async = query.BeginExecute(null, null);
var task = System.Threading.Tasks.Task.Factory.FromAsync<Account>(async, (result) =>
{
return query.EndExecute(result).First(); // <- Exception thrown here
});
textBox1.Dispatcher.BeginInvoke(() =>
{
textBox1.Text = task.Result.Name;
});
}
看來幾乎是顯而易見的,我很想念在線程如何使用權限的一些基礎知識。由於在我的情況下使用單獨的線程是可取的,有沒有辦法「複製」權限/認證?也許是某種模仿?
編輯:如果其他任何人正在努力與此,使用其他線程(或Task
,視情況而定)是可能的,只要在UI線程上執行query.BeginExecute(null, null);
。您需要一種方法將返回的IAsyncResult
恢復到調用線程,但您可以使用ManualResetEvent
來完成此操作。
但我還是想知道爲什麼該死的權限/驗證不是線程之間共享...
它可能涉及到[當前線程的執行上下文(http://msdn.microsoft.com/en-us/library什麼/system.threading.thread.executioncontext)。 – shambulator
很有可能,但是我想指出的是,在本地,本地CRM服務器上測試我的代碼時,一切正常。所以,現在還不清楚究竟發生了什麼。 – Shaamaan