Ich weiß nicht, ob ich etwas falsch mache oder ich habe einen Fehler in der Async-Bibliothek gefunden, aber ich habe ein Problem beim Ausführen von Async-Code nach I gesehen kehrte mit continueWith() in den synchronisierten Kontext zurück.ConfigureAwait (False) ändert den Kontext nicht nach ContinueWith()
UPDATE: Der Code läuft jetzt
using System;
using System.ComponentModel;
using System.Net.Http;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
internal static class Program
{
[STAThread]
private static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
MainFrameController controller = new MainFrameController(this);
//First async call without continueWith
controller.DoWork();
//Second async call with continueWith
controller.DoAsyncWork();
}
public void Callback(Task<HttpResponseMessage> task)
{
Console.Write(task.Result); //IT WORKS
MainFrameController controller =
new MainFrameController(this);
//third async call
controller.DoWork(); //IT WILL DEADLOCK, since ConfigureAwait(false) in HttpClient DOESN'T change context
}
}
internal class MainFrameController
{
private readonly Form1 form;
public MainFrameController(Form1 form)
{
this.form = form;
}
public void DoAsyncWork()
{
Task<HttpResponseMessage> task = Task<HttpResponseMessage>.Factory.StartNew(() => DoWork());
CallbackWithAsyncResult(task);
}
private void CallbackWithAsyncResult(Task<HttpResponseMessage> asyncPrerequisiteCheck)
{
asyncPrerequisiteCheck.ContinueWith(task =>
form.Callback(task),
TaskScheduler.FromCurrentSynchronizationContext());
}
public HttpResponseMessage DoWork()
{
MyHttpClient myClient = new MyHttpClient();
return myClient.RunAsyncGet().Result;
}
}
internal class MyHttpClient
{
public async Task<HttpResponseMessage> RunAsyncGet()
{
HttpClient client = new HttpClient();
return await client.GetAsync("https://www.google.no").ConfigureAwait(false);
}
}
partial class Form1
{
private IContainer components;
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Text = "Form1";
}
#endregion
}
}
- Der Httpclient-Code, der async ist gut läuft das erste Mal.
- Dann führe ich den zweiten Async-Code und zurück zum UI-Kontext mit ContinueWith, und es funktioniert gut.
- Ich führe den HttClient-Code erneut, aber es Deadlock, weil dieses Mal ConfigureAwait (false) den Kontext nicht ändert.
Es wäre schön, wenn dies ein tatsächliches * vollständiges * Beispiel wäre, das das Problem demonstriert. Leider ist es nicht, also würden wir raten. Wenn Sie könnten, versuchen Sie bitte ein [mcve] zu erstellen. –
Hallo, wäre es schön zu wissen, was Sie wirklich erreichen möchten. Da Sie verschiedene Techniken für asynchrone Operationen mischen, ist der Code schwer zu verstehen. Zum Beispiel wird die RunAsyncPost-Methode als DoHttpWork aufgerufen. –