c# multithreading task-parallel-library dynamics-crm-2011 silverlight-5.0

c# - ¿Copiar permisos/autenticación a hilos secundarios...?



multithreading task-parallel-library (1)

No estoy muy seguro, esto ayudará. Pero encontré una descripción de por Jeffrey Richter página 770

"Al igual que las aplicaciones de consola, ASP.NET Web Form y XML Web Service permiten que cualquier subproceso haga lo que quiera. Cuando un subproceso de subprocesos comienza a procesar la solicitud de un cliente, puede asumir la cultura del cliente (System.Globalization.CultureInfo), permitiendo que el servidor web devuelva el formato específico de la cultura para números, fechas y horas.5 Además, el servidor web puede asumir la identidad del cliente (System.Security.Principal. IPrincipal) para que el servidor pueda acceder solo a los recursos que el servidor al cliente se le permite acceder. Cuando un subproceso de subprocesos genera una operación asincrónica, se completará con otro subproceso de subprocesos, que procesará el resultado de una operación asíncrona. Mientras este trabajo se realiza en nombre de la solicitud del cliente original , la información de cultura e identidad no fluye al nuevo grupo de subprocesos por defecto, por lo que cualquier trabajo adicional realizado en nombre del cliente ahora no está utilizando la información de identidad y cultura del cliente. De todos modos, queremos que la cultura y la información de identidad fluyan a los otros subprocesos del grupo de subprocesos que aún están trabajando en nombre del mismo cliente ".

Y aquí está su ejemplo, espero que esto ayude.

private static AsyncCallback SyncContextCallback(AsyncCallback callback) { SynchronizationContext sc = SynchronizationContext.Current; // If there is no SC, just return what was passed in if (sc == null) return callback; // Return a delegate that, when invoked, posts to the captured SC a method that // calls the original AsyncCallback passing it the IAsyncResult argument return asyncResult => sc.Post(result => callback((IAsyncResult)result), asyncResult); } protected override void OnMouseClick(MouseEventArgs e) { // The GUI thread initiates the asynchronous Web request Text = "Web request initiated"; var webRequest = WebRequest.Create("http://Wintellect.com/"); webRequest.BeginGetResponse(SyncContextCallback(ProcessWebResponse), webRequest); base.OnMouseClick(e); } private void ProcessWebResponse(IAsyncResult result) { // If we get here, this must be the GUI thread, it''s OK to update the UI var webRequest = (WebRequest)result.AsyncState; using (var webResponse = webRequest.EndGetResponse(result)) { Text = "Content length: " + webResponse.ContentLength; } }

Y aquí está lo que estoy usando en mi aplicación.

public override void UpdateCanvas(object parameter) { Action<GraphPane> startToUpdate = StartToUpdate; GraphPane selectedPane = Canvas.HostingPane.PaneList.Find(p => p.Title.Text.Equals(defaultPanTitle)); startToUpdate.BeginInvoke(selectedPane, FormSyncContext.SyncContextCallback(RefreshCanvas), selectedPane); } public static AsyncCallback SyncContextCallback(AsyncCallback callback) { // Capture the calling thread''s SynchronizationContext-derived object SynchronizationContext sc = SynchronizationContext.Current; // If there is no SC, just return what was passed in if (sc == null) return callback; // Return a delegate that, when invoked, posts to the captured SC a method that // calls the original AsyncCallback passing it the IAsyncResult argument return asyncResult => sc.Post(result => callback((IAsyncResult)result), asyncResult); }

Aquí hay algo muy raro que había notado.

Estoy escribiendo una extensión de Silverlight CRM 2011 y, bueno, todo está bien en mi instancia de desarrollo local. La aplicación usa OData para comunicarse, y usa System.Threading.Tasks.Task mucho para realizar todas las operaciones en segundo plano ( FromAsync es una bendición).

Sin embargo, decidí probar mi aplicación en CRM 2011 Online y, para mi sorpresa, encontré que ya no funcionaría; Recibiría una excepción de seguridad al finalizar las tareas de recuperación.

Usando Fiddler, encontré que CRM está intentando redirigirme a la página de inicio de sesión de Live, lo cual no tenía mucho sentido, considerando que ya estaba conectado.

Después de algunos intentos más, descubrí que los errores se debían a que estaba accediendo al servicio desde un subproceso diferente al del subproceso de la interfaz de usuario.

Aquí hay un ejemplo rápido:

//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; }); }

Parece casi obvio que me faltan algunos fundamentos sobre cómo los subprocesos usan los permisos. Ya que es preferible usar un hilo separado en mi caso, ¿hay alguna forma de "copiar" los permisos / autenticación? ¿Quizás algún tipo de personificación?

EDITAR: En caso de que alguien más esté luchando con esto, es posible utilizar otros subprocesos (o Task , según sea el caso) siempre y cuando query.BeginExecute(null, null); Se ejecuta en el hilo de la interfaz de usuario. Necesita una forma de recuperar el IAsyncResult devuelto al subproceso de llamada, pero puede hacerlo utilizando un ManualResetEvent .

Pero todavía me gustaría saber por qué los permisos / autenticación no se comparten entre los hilos ...