简体   繁体   English

使用主线程而不阻塞它的异步方法示例。#

[英]Example of an Async Method that uses the main thread without blocking it.c#

In the page 18 Concurrency in C# Cookbook,Stephen Cleary define Asynchronous Programming : "A form of concurrency that uses futures or callbacks to avoid unnecessary threads." 在18#Concurrency in C#Cookbook中,Stephen Cleary定义了异步编程:“一种使用期货或回调来避免不必要线程的并发形式。” but in code all Async Method uses multi threads (Thread Pool). 但在代码中,所有异步方法都使用多线程(线程池)。 Can same one please show me an example of an Async Method that uses the main thread without blocking it. 同一个请给我一个异步方法的例子,它使用主线程而不阻塞它。

Consider, for example, a method that sends some http request and gives you some http response. 例如,考虑一种发送一些http请求并为您提供一些http响应的方法。 If this method would be synchronous (eg WebRequest.GetResponse() ) then 90% time this method would just wait due to network latency, and hence Thread on which this method executed would just sleep and do nothing. 如果这个方法是同步的(例如WebRequest.GetResponse() )那么由于网络延迟,这个方法只会等待90%的时间,因此执行此方法的线程只会睡眠并且什么都不做。

When you using an async method (eg HttpClient.PostAsync() ) and await the result, then the calling method ends with the first await , so the calling thread is free to process other work or can be returned to ThreadPool. 当您使用异步方法(例如HttpClient.PostAsync() )并等待结果时,调用方法以第一个await结束,因此调用线程可以自由处理其他工作或可以返回到ThreadPool。 When your http response is received, then your work will be resumed. 收到您的http响应后,您的工作将恢复。

The Thread on which the continuation will run depends on the SynchronizationContext . 将继续运行的线程取决于SynchronizationContext So, if you ran and awaited an Async method from the UI thread, then the continuation will run on the UI thread. 因此,如果您从UI线程运行并等待Async方法,则继续将在UI线程上运行。 If you ran and awaited an async method from background thread then the continuation will run on some ThreadPool Thread. 如果您从后台线程运行并等待异步方法,则继续将在某些ThreadPool线程上运行。

async void button_click(object sender, EventArgs args)
{
    _button.Enabled = false; // this is invoked on main thread

    var response = await _httpClient.PostAsync(request); 
    // you will not block main thread and your UI will be responsive
    // also you won't occupy ThreadPool thread for all the time to get the response

    ProcessResponse(response); // this is invoked on main thread
}

Some Async methods would just run in the background and occupy a background thread for all the time they needed to be completed, and some (IO basically) would not. 一些Async方法只会在后台运行并占用后台线程,因为它们需要完成所有时间,而有些(IO基本上)则不会。

Consider this simple windows form program: 考虑这个简单的Windows窗体程序:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    protected override void OnLoad(EventArgs e)
    {
        GetPoint();
    }

    public async void GetPoint()
    {
        var point = await RetrivePointAsync();
        MessageBox.Show(point.ToString());
    }

    public Task<Point> RetrivePointAsync()
    {
        return Task.Factory.FromAsync<Point>(
             (callback, state) => new Handler(this, callback),
             x => ((Handler)x).Point, null);
    }
}



class Handler : IAsyncResult
{
    AsyncCallback _calback;
    public Point Point { get; set; }
    public object AsyncState { get { return null; } }
    public bool CompletedSynchronously { get { return false; } }
    public bool IsCompleted { get; set; }

    public WaitHandle AsyncWaitHandle { get { return null; } }

    public Handler(Control control, AsyncCallback calback)
    {
        _calback = calback;
        control.MouseDown += control_MouseDown;
    }

    void control_MouseDown(object sender, MouseEventArgs e)
    {
        Point = e.Location;
        IsCompleted = true;
        _calback(this);
    }
}

As you see no new threads are created to create async method. 如您所见,没有创建新线程来创建异步方法。 My custom handler just wraps mouse down event on a form. 我的自定义处理程序只是将鼠标按下事件包装在窗体上。

Not all async methods require a dedicated thread. 并非所有异步方法都需要专用线程。 Typically, those waiting for an I/O completion don't necessarily require a thread. 通常,等待I / O完成的那些不一定需要线程。

TaskCompletionSource allows such scenario TaskCompletionSource允许这样的场景

This is example from "CLR via C#" book: 这是“CLR via C#”一书的例子:

private static async Task<String> IssueClientRequestAsync(String serverName, String message) { 
   using (var pipe = new NamedPipeClientStream(serverName, "PipeName", PipeDirection.InOut,  
      PipeOptions.Asynchronous | PipeOptions.WriteThrough)) { 
      pipe.Connect(); // Must Connect before setting ReadMode 
      pipe.ReadMode = PipeTransmissionMode.Message; 
      // Asynchronously send data to the server 
      Byte[] request = Encoding.UTF8.GetBytes(message); 
      await pipe.WriteAsync(request, 0, request.Length); 
      // Asynchronously read the server's response 
      Byte[] response = new Byte[1000]; 
      Int32 bytesRead = await pipe.ReadAsync(response, 0, response.Length); 
      return Encoding.UTF8.GetString(response, 0, bytesRead); 
   }  // Close the pipe 
} 

Here executing thread is released just after WriteAsync call. 这里执行线程在WriteAsync调用之后WriteAsync After network driver completes its work, execution will continue until ReadAsync, when thread will be released again until data is read. 在网络驱动程序完成其工作后,执行将继续执行直到ReadAsync,此时线程将再次释放,直到读取数据。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Unity中的C#:在不阻塞主线程的情况下调用Promise Style Async方法 - C# in Unity: Calling Promise Style Async method without Blocking the Main Thread 等待异步方法而不阻塞线程 - Wait for async method without blocking the thread 如何在不阻塞主线程的情况下返回异步HttpWebResponse? - How to return an async HttpWebResponse without blocking the main thread? 如何在不阻塞主线程的情况下调用异步函数同步? - How to call an async function synchronized without blocking the main thread? 为什么带有await关键字的异步方法仍然阻塞主线程? - Why is an async method with await keyword still blocking the main thread? 在async / await上阻塞主线程 - blocking main thread on async/await 在同步方法中等待异步方法而不阻塞线程 - Waiting async method inside sync method without blocking the thread 等待调用异步方法的Task完成而不阻塞线程 - wait for a Task that calls an async method to complete without blocking thread 如何在不阻塞主线程的情况下暂停 C# 代码执行? - How to Pause C# code execution without blocking main thread? 运行一个使用主线程中的方法的单独线程是否仍然在主线程上运行它? (C#) - Will running a separate thread that uses a method from the main thread still run it on the main thread? (C#)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM