Dari pemahaman saya salah satu hal utama yang async
dan menunggu
lakukan adalah untuk membuat kode mudah untuk membaca dan menulis, tetapi menggunakan mereka sama dengan pemijahan latar belakang benang untuk melakukan durasi panjang logika?
I'm saat ini mencoba keluar yang paling dasar contoh. I've menambahkan beberapa komentar inline. Dapatkah anda menjelaskan hal ini untuk saya?
// I don't understand why this method must be marked as `async`.
private async void button1_Click(object sender, EventArgs e)
{
Task<int> access = DoSomethingAsync();
// task independent stuff here
// this line is reached after the 5 seconds sleep from
// DoSomethingAsync() method. Shouldn't it be reached immediately?
int a = 1;
// from my understanding the waiting should be done here.
int x = await access;
}
async Task<int> DoSomethingAsync()
{
// is this executed on a background thread?
System.Threading.Thread.Sleep(5000);
return 1;
}
Ketika menggunakan async
dan menunggu
compiler menghasilkan keadaan mesin di latar belakang.
Berikut ini's contoh di mana saya berharap aku bisa menjelaskan beberapa rincian tingkat tinggi yang terjadi:
public async Task MyMethodAsync()
{
Task<int> longRunningTask = LongRunningOperationAsync();
// independent work which doesn't need the result of LongRunningOperationAsync can be done here
//and now we call await on the task
int result = await longRunningTask;
//use the result
Console.WriteLine(result);
}
public async Task<int> LongRunningOperationAsync() // assume we return an int from this long running operation
{
await Task.Delay(1000); // 1 second delay
return 1;
}
OK, jadi apa yang terjadi di sini:
Tugas<int> longRunningTask = LongRunningOperationAsync();
mulai mengeksekusi LongRunningOperation
Bekerja independen dilakukan di let's asumsikan Utama Benang (Thread ID = 1) maka menanti longRunningTask
tercapai.
Sekarang, jika longRunningTask
tidak't selesai dan masih berjalan, MyMethodAsync()
akan kembali memanggil metode, dengan demikian thread utama doesn't mendapatkan diblokir. Ketika longRunningTask
ini dilakukan maka thread dari ThreadPool (dapat berupa benang) akan kembali ke MyMethodAsync()
yang sebelumnya konteks dan melanjutkan eksekusi (dalam hal ini pencetakan hasil untuk konsol).
Kedua kasus akan bahwa longRunningTask
sudah selesai pelaksanaannya dan hasilnya tersedia. Ketika mencapai menanti longRunningTask
kami sudah memiliki hasil jadi kode akan terus mengeksekusi pada thread yang sama. (dalam hal ini hasil cetak untuk konsol). Tentu saja hal ini tidak terjadi untuk contoh di atas, di mana ada's Tugas.Delay(1000)
yang terlibat.
Dari pemahaman saya salah satu hal utama yang async dan menanti lakukan adalah untuk membuat kode mudah untuk menulis dan membaca.
Mereka're untuk membuat asynchronous kode mudah untuk menulis dan membaca, ya.
itu hal yang sama seperti pemijahan latar belakang benang untuk melakukan durasi panjang logika?
Tidak di semua.
// I don't mengerti mengapa metode ini harus ditandai sebagai 'async'.
The async
kata kunci memungkinkan menunggu
kata kunci. Jadi apapun metode yang menggunakan menunggu
harus ditandai async
.
// baris Ini tercapai setelah 5 detik tidur dari DoSomethingAsync() metode. Seharusnya't itu dicapai dengan segera?
Tidak, karena async
metode yang tidak berjalan di thread lain secara default.
// ini dijalankan di latar belakang thread?
No.
Anda dapat menemukan saya async
/menunggu
intro bermanfaat. The official MSDN docs juga luar biasa baik (terutama KETUK bagian), dan async
tim mengeluarkan istimewa FAQ.
Berikut adalah contoh singkat dari async/menanti pada tingkat tinggi. Ada banyak rincian lebih lanjut untuk mempertimbangkan yang melampaui ini.
Catatan: Tugas.Delay(1000)
mensimulasikan melakukan pekerjaan selama 1 detik. Saya pikir itu's terbaik untuk berpikir tentang hal ini seperti menunggu respons dari sumber eksternal. Sejak kode kami menunggu respon, sistem dapat mengatur menjalankan tugas ke samping dan kembali ke sana setelah itu's selesai. Sementara itu, dapat melakukan beberapa pekerjaan lain di thread itu.
Dalam contoh di bawah ini, blok pertama melakukan persis seperti itu. Dimulai semua tugas-tugas yang segera (pada Task.Delay
garis-garis) dan menetapkan mereka ke samping. Kode akan berhenti pada menunggu
sampai 1 detik penundaan ini dilakukan sebelum pergi ke baris berikutnya. Sejak b
, c
, d
, dan e
semua mulai melaksanakan pada saat yang hampir sama persis time sebagai a
(karena kurangnya menunggu), mereka harus finish pada kira-kira waktu yang sama dalam kasus ini.
Dalam contoh di bawah ini, blok kedua mulai tugas dan menunggu untuk itu untuk menyelesaikan (yang adalah apa yang menunggu
tidak) sebelum memulai tugas berikutnya. Setiap iterasi ini membutuhkan waktu 1 detik. Yang menunggu
berhenti program dan menunggu hasilnya sebelum melanjutkan. Ini adalah perbedaan utama antara pertama dan kedua blok.
Console.WriteLine(DateTime.Now);
// This block takes 1 second to run because all
// 5 tasks are running simultaneously
{
var a = Task.Delay(1000);
var b = Task.Delay(1000);
var c = Task.Delay(1000);
var d = Task.Delay(1000);
var e = Task.Delay(1000);
await a;
await b;
await c;
await d;
await e;
}
Console.WriteLine(DateTime.Now);
// This block takes 5 seconds to run because each "await"
// pauses the code until the task finishes
{
await Task.Delay(1000);
await Task.Delay(1000);
await Task.Delay(1000);
await Task.Delay(1000);
await Task.Delay(1000);
}
Console.WriteLine(DateTime.Now);
OUTPUT:
5/24/2017 2:22:50 PM
5/24/2017 2:22:51 PM (First block took 1 second)
5/24/2017 2:22:56 PM (Second block took 5 seconds)
Catatan: Ini adalah di mana hal-hal yang sedikit berkabut, bagi saya, jadi jika saya'm yang salah pada apa pun, tolong koreksi saya dan saya akan update jawabannya. It's penting untuk memiliki pemahaman dasar tentang bagaimana ini bekerja, tetapi anda bisa mendapatkan dengan tanpa menjadi seorang ahli asalkan anda tidak pernah menggunakan ConfigureAwait(palsu)
, meskipun kemungkinan besar anda akan kehilangan pada beberapa kesempatan untuk optimasi, saya berasumsi.
Ada satu aspek ini yang membuat async/menunggu konsep yang agak rumit untuk dipahami. Yang's kenyataan bahwa dalam contoh ini, semua ini terjadi pada benang yang sama (atau setidaknya apa yang tampaknya menjadi thread yang sama dalam hal SynchronizationContext). Secara default, menunggu
akan mengembalikan sinkronisasi konteks original thread yang sedang berjalan di. Misalnya, di ASP.NET anda memiliki HttpContext yang terikat benang ketika permintaan masuk. Konteks ini berisi hal-hal tertentu dengan aslinya Http request seperti aslinya Permintaan objek yang memiliki hal-hal seperti bahasa, alamat IP, header, dll. Jika anda beralih benang setengah jalan melalui pengolahan sesuatu, anda bisa berpotensi akhirnya mencoba untuk menarik informasi dari objek ini pada berbagai HttpContext yang bisa menjadi bencana. Jika anda tahu anda tidak't dapat menggunakan konteks untuk apa pun, anda dapat memilih untuk "tidak peduli" tentang hal itu. Ini pada dasarnya memungkinkan kode anda untuk berjalan pada thread terpisah tanpa membawa konteks main dengan hal itu.
Bagaimana anda mencapai hal ini? Secara default, menunggu;
kode benar-benar membuat asumsi bahwa anda ingin menangkap dan mengembalikan konteks:
await a; //Same as the line below
await a.ConfigureAwait(true);
Jika anda ingin untuk memungkinkan kode utama untuk melanjutkan thread baru tanpa konteks aslinya, anda hanya menggunakan palsu bukannya benar sehingga tahu itu doesn't perlu untuk mengembalikan konteks.
await a.ConfigureAwait(false);
Setelah program selesai menjadi berhenti, ia akan terus potentially yang sama sekali berbeda benang dengan konteks yang berbeda. Ini adalah di mana peningkatan kinerja yang akan datang dari -- bisa melanjutkan pada setiap benang tersedia tanpa harus mengembalikan asli konteks ini dimulai dengan.
Hal ini membingungkan? Hell yeah! Anda bisa mengetahuinya? Mungkin! Setelah anda memiliki pemahaman tentang konsep-konsep, kemudian pindah ke Stephen Cleary's penjelasan yang cenderung diarahkan lebih ke arah seseorang dengan pemahaman teknis async/sudah menunggu.
Lanjut ke jawaban yang lain, silahkan lihat di menanti (C# Referensi)
dan lebih khusus lagi di contoh termasuk, menjelaskan situasi anda sedikit
Windows berikut Bentuk contoh ini menggambarkan penggunaan menunggu di sebuah metode async, WaitAsynchronouslyAsync. Sebaliknya perilaku yang metode dengan perilaku WaitSynchronously. Tanpa menunggu operator diterapkan untuk tugas, WaitSynchronously berjalan serentak meskipun menggunakan async pengubah dalam definisi dan panggilan untuk Benang.Tidur dalam tubuh.
private async void button1_Click(object sender, EventArgs e)
{
// Call the method that runs asynchronously.
string result = await WaitAsynchronouslyAsync();
// Call the method that runs synchronously.
//string result = await WaitSynchronously ();
// Display the result.
textBox1.Text += result;
}
// The following method runs asynchronously. The UI thread is not
// blocked during the delay. You can move or resize the Form1 window
// while Task.Delay is running.
public async Task<string> WaitAsynchronouslyAsync()
{
await Task.Delay(10000);
return "Finished";
}
// The following method runs synchronously, despite the use of async.
// You cannot move or resize the Form1 window while Thread.Sleep
// is running because the UI thread is blocked.
public async Task<string> WaitSynchronously()
{
// Add a using directive for System.Threading.
Thread.Sleep(10000);
return "Finished";
}
Menunjukkan penjelasan-penjelasan diatas dalam tindakan yang sederhana console program -
class Program
{
static void Main(string[] args)
{
TestAsyncAwaitMethods();
Console.WriteLine("Press any key to exit...");
Console.ReadLine();
}
public async static void TestAsyncAwaitMethods()
{
await LongRunningMethod();
}
public static async Task<int> LongRunningMethod()
{
Console.WriteLine("Starting Long Running method...");
await Task.Delay(5000);
Console.WriteLine("End Long Running method...");
return 1;
}
}
Dan output adalah:
Starting Long Running method...
Press any key to exit...
End Long Running method...
Dengan demikian,
Dengan demikian, tidak thread diblokir.
Saya pikir anda've mengambil contoh yang buruk dengan Sistem.Threading.Benang.Tidur
Titik async
Tugas adalah untuk membiarkan hal itu mengeksekusi di latar belakang tanpa mengunci thread utama, seperti melakukan DownloadFileAsync
Sistem.Threading.Benang.Tidur
isn't sesuatu yang "yang sedang dilakukan", itu hanya tidur, dan oleh karena itu anda baris berikutnya tercapai setelah 5 detik ...
Baca artikel ini, saya pikir itu adalah penjelasan dari async
dan menunggu
konsep: http://msdn.microsoft.com/en-us/library/vstudio/hh191443.aspx
Berikut adalah cepat console program untuk membuat jelas kepada orang-orang yang mengikuti. "TaskToDo" metode lama anda menjalankan metode yang anda inginkan untuk membuat async. Sehingga menjalankan Async dilakukan oleh TestAsync metode. Tes loop metode hanya berjalan melalui "TaskToDo" tugas-tugas dan menjalankan mereka Async. Anda dapat melihat bahwa dalam hasil karena mereka don't lengkap dalam urutan yang sama dari berjalan ke berjalan - mereka melaporkan ke konsol UI benang ketika mereka selesai. Sederhana, tapi saya pikir sederhana contoh membawa inti dari pola yang lebih baik dari lebih terlibat contoh:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace TestingAsync
{
class Program
{
static void Main(string[] args)
{
TestLoops();
Console.Read();
}
private static async void TestLoops()
{
for (int i = 0; i < 100; i++)
{
await TestAsync(i);
}
}
private static Task TestAsync(int i)
{
return Task.Run(() => TaskToDo(i));
}
private async static void TaskToDo(int i)
{
await Task.Delay(10);
Console.WriteLine(i);
}
}
}
Semua jawaban berikut gunakan Tugas.Delay() atau beberapa lainnya dibangun di async function. Tapi di sini adalah contoh yang menggunakan satu pun dari mereka async fungsi:
// Starts counting to a large numbewr and then immediately displays message "i'm counting...".
// Then it waits for task to finish and displays "finished, press any key".
static void asyncTest ()
{
Console.WriteLine("Started asyncTest()");
Task<long> task = asyncTest_count();
Console.WriteLine("Started counting, please wait...");
task.Wait(); // if you comment this line you will see that message "Finished counting" will be displayed before we actually finished counting.
//Console.WriteLine("Finished counting to " + task.Result.ToString()); // using task.Result seems to also call task.Wait().
Console.WriteLine("Finished counting.");
Console.WriteLine("Press any key to exit program.");
Console.ReadLine();
}
static async Task<long> asyncTest_count()
{
long k = 0;
Console.WriteLine("Started asyncTest_count()");
await Task.Run(() =>
{
long countTo = 100000000;
int prevPercentDone = -1;
for (long i = 0; i <= countTo; i++)
{
int percentDone = (int)(100 * (i / (double)countTo));
if (percentDone != prevPercentDone)
{
prevPercentDone = percentDone;
Console.Write(percentDone.ToString() + "% ");
}
k = i;
}
});
Console.WriteLine("");
Console.WriteLine("Finished asyncTest_count()");
return k;
}
Jawaban ini bertujuan untuk memberikan beberapa info yang spesifik untuk ASP.NET.
Dengan memanfaatkan async/menanti dalam MVC controller, adalah mungkin untuk meningkatkan benang renang pemanfaatan dan mencapai banyak throughput yang lebih baik, seperti yang dijelaskan dalam artikel di bawah ini,
http://www.asp.net/mvc/tutorials/mvc-4/using-asynchronous-methods-in-aspnet-mvc-4
Di aplikasi web yang melihat sejumlah besar permintaan bersamaan di start-up atau memiliki bursty beban (mana concurrency meningkatkan tiba-tiba), membuat web service panggilan asynchronous akan meningkatkan respon dari aplikasi anda. Permintaan asynchronous mengambil jumlah waktu yang sama untuk proses sinkron permintaan. Misalnya, jika permintaan membuat panggilan layanan web yang membutuhkan dua detik untuk lengkap, permintaan memakan waktu dua detik apakah itu dilakukan serempak atau asinkron. Namun, selama panggilan asynchronous, benang tidak diblokir dari menanggapi permintaan lainnya saat ini menunggu permintaan pertama untuk menyelesaikan. Oleh karena itu, asynchronous permintaan mencegah permintaan antrian dan benang renang pertumbuhan ketika ada banyak permintaan bersamaan yang memanggil operasi berjalan lama.
Jujur saya masih berpikir penjelasan terbaik tentang masa depan dan menjanjikan di Wikipedia: http://en.wikipedia.org/wiki/Futures_and_promises
Ide dasarnya adalah bahwa anda memiliki kolam renang yang terpisah dari benang yang melaksanakan tugas-tugas secara asinkron. Ketika menggunakannya. Objek namun tidak membuat janji bahwa ia akan menjalankan operasi pada beberapa waktu dan memberikan hasil ketika anda memintanya. Ini berarti bahwa hal itu akan menghambat ketika anda meminta hasil dan belum't selesai, tapi jalankan di thread renang sebaliknya.
Dari sana anda dapat mengoptimalkan hal-hal: beberapa operasi dapat dilaksanakan async dan anda dapat mengoptimalkan hal-hal seperti file IO dan jaringan komunikasi oleh batching bersama-sama permintaan berikutnya dan/atau penataan kembali mereka. I'm tidak yakin jika ini adalah sudah dalam tugas framework dari Microsoft, tetapi jika itu tidak't yang akan menjadi salah satu hal pertama yang saya akan menambahkan.
Anda dapat benar-benar menerapkan pola masa depan memilah-dengan hasil yang di C# 4.0. Jika anda ingin tahu bagaimana cara kerjanya persis, saya dapat merekomendasikan link ini yang melakukan pekerjaan yang layak: http://code.google.com/p/fracture/source/browse/trunk/Squared/TaskLib/ . Namun, jika anda mulai bermain-main dengan diri sendiri, anda akan melihat bahwa anda benar-benar membutuhkan dukungan bahasa jika anda ingin melakukan semua hal-hal keren-yang adalah apa yang Microsoft lakukan.
Sebenarnya Async / Menanti adalah sepasang kata kunci yang hanya sintaksis gula untuk membuat panggilan balik dari asynchronous tugas.
Ambil contoh operasi ini:
public static void DoSomeWork()
{
var task = Task.Run(() =>
{
// [RUNS ON WORKER THREAD]
// IS NOT bubbling up due to the different threads
throw new Exception();
Thread.Sleep(2000);
return "Hello";
});
// This is the callback
task.ContinueWith((t) => {
// -> Exception is swallowed silently
Console.WriteLine("Completed");
// [RUNS ON WORKER THREAD]
});
}
Kode di atas memiliki beberapa kelemahan. Kesalahan yang tidak diteruskan dan itu's sulit untuk dibaca. Tapi Async dan Menunggu datang untuk membantu kami keluar:
public async static void DoSomeWork()
{
var result = await Task.Run(() =>
{
// [RUNS ON WORKER THREAD]
// IS bubbling up
throw new Exception();
Thread.Sleep(2000);
return "Hello";
});
// every thing below is a callback
// (including the calling methods)
Console.WriteLine("Completed");
}
Menunggu panggilan harus di Async metode. Ini memiliki beberapa keuntungan:
CATATAN: Async dan Menanti digunakan dengan panggilan asynchronous tidak untuk membuat ini. Anda harus menggunakan Tugas Perpustakaan selama ini, seperti Tugas.Run() .
Berikut ini adalah perbandingan antara menunggu dan tidak menunggu solusi
Ini adalah tidak ada async solusi:
public static long DoTask()
{
stopWatch.Reset();
stopWatch.Start();
// [RUNS ON MAIN THREAD]
var task = Task.Run(() => {
Thread.Sleep(2000);
// [RUNS ON WORKER THREAD]
});
// goes directly further
// WITHOUT waiting until the task is finished
// [RUNS ON MAIN THREAD]
stopWatch.Stop();
// 50 milliseconds
return stopWatch.ElapsedMilliseconds;
}
Ini adalah metode async:
public async static Task<long> DoAwaitTask()
{
stopWatch.Reset();
stopWatch.Start();
// [RUNS ON MAIN THREAD]
await Task.Run(() => {
Thread.Sleep(2000);
// [RUNS ON WORKER THREAD]
});
// Waits until task is finished
// [RUNS ON MAIN THREAD]
stopWatch.Stop();
// 2050 milliseconds
return stopWatch.ElapsedMilliseconds;
}
Anda dapat benar-benar memanggil sebuah metode async tanpa menunggu kata kunci tetapi ini berarti bahwa ada Pengecualian di sini adalah tertelan dalam rilis mode:
public static Stopwatch stopWatch { get; } = new Stopwatch();
static void Main(string[] args)
{
Console.WriteLine("DoAwaitTask: " + DoAwaitTask().Result + " ms");
// 2050 (2000 more because of the await)
Console.WriteLine("DoTask: " + DoTask() + " ms");
// 50
Console.ReadKey();
}
Async dan Menunggu tidak dimaksudkan untuk komputasi paralel. Mereka digunakan untuk tidak memblokir thread utama. Ketika itu's tentang asp.net atau aplikasi Windows, memblokir thread utama karena jaringan panggilan adalah hal yang buruk. Jika anda melakukan ini, aplikasi anda akan mendapatkan tidak responsif atau bahkan kecelakaan.
Check out ms docs untuk lebih banyak contoh.
Melihat ini biola https://dotnetfiddle.net/VhZdLU (dan memperbaikinya jika memungkinkan) untuk menjalankan sederhana aplikasi konsol yang menunjukkan penggunaan Tugas, Tugas.WaitAll(), async dan menunggu operator dalam program yang sama.
Ini biola harus anda eksekusi konsep siklus.
Berikut ini adalah contoh kode
using System;
using System.Threading.Tasks;
public class Program
{
public static void Main()
{
var a = MyMethodAsync(); //Task started for Execution and immediately goes to Line 19 of the code. Cursor will come back as soon as await operator is met
Console.WriteLine("Cursor Moved to Next Line Without Waiting for MyMethodAsync() completion");
Console.WriteLine("Now Waiting for Task to be Finished");
Task.WaitAll(a); //Now Waiting
Console.WriteLine("Exiting CommandLine");
}
public static async Task MyMethodAsync()
{
Task<int> longRunningTask = LongRunningOperation();
// independent work which doesn't need the result of LongRunningOperationAsync can be done here
Console.WriteLine("Independent Works of now executes in MyMethodAsync()");
//and now we call await on the task
int result = await longRunningTask;
//use the result
Console.WriteLine("Result of LongRunningOperation() is " + result);
}
public static async Task<int> LongRunningOperation() // assume we return an int from this long running operation
{
Console.WriteLine("LongRunningOperation() Started");
await Task.Delay(2000); // 2 second delay
Console.WriteLine("LongRunningOperation() Finished after 2 Seconds");
return 1;
}
}
Async & Menanti Penjelasan Sederhana
Analogi Sederhana
Seseorang mungkin menunggu untuk kereta pagi. Ini semua mereka lakukan karena ini adalah tugas utama mereka bahwa saat ini mereka sedang melakukan. (sinkron pemrograman (apa yang biasanya anda lakukan!))
Orang lain mungkin menunggu pagi mereka melatih sementara mereka bebas rokok dan kemudian minum kopi mereka. (Asynchronous pemrograman)
Apa itu pemrograman asynchronous?
Asynchronous pemrograman adalah di mana seorang programmer akan memilih untuk menjalankan beberapa kode nya di thread terpisah dari thread utama dari eksekusi dan kemudian memberitahu thread utama pada itu's penyelesaian.
Apa async kata kunci benar-benar melakukannya?
Awalan async kata kunci untuk nama metode seperti
async void DoSomething(){ . . .
memungkinkan programmer untuk menggunakan menunggu kata kunci saat panggilan asynchronous tugas. Yang's semua itu.
Mengapa hal ini penting?
Dalam banyak sistem perangkat lunak thread utama ini diperuntukkan bagi operasi-operasi khusus yang berkaitan dengan User Interface. Jika saya berjalan sangat kompleks rekursif algoritma yang membutuhkan waktu 5 detik untuk menyelesaikan di komputer saya, tapi saya menjalankan ini di Thread Utama (UI benang) Ketika pengguna mencoba untuk klik pada apa pun di aplikasi saya, itu akan muncul untuk menjadi beku seperti saya thread utama telah antri dan saat ini sedang memproses terlalu banyak operasi. Akibatnya thread utama tidak dapat memproses klik mouse untuk menjalankan metode dari tombol klik.
Ketika anda menggunakan Async dan Menunggu?
Penggunaan asynchronous kata kunci pilihan ketika anda melakukan sesuatu yang doesn't melibatkan user interface.
Jadi katakanlah anda're menulis sebuah program yang memungkinkan pengguna untuk membuat sketsa pada ponsel mereka tapi setiap 5 detik itu akan memeriksa cuaca di internet.
Kami harus menunggu panggilan pemungutan suara panggilan setiap 5 detik ke jaringan untuk mendapatkan cuaca sebagai pengguna dari aplikasi kebutuhan untuk tetap berinteraksi dengan ponsel layar sentuh untuk menggambar gambar-gambar cantik.
* Bagaimana anda menggunakan Async dan Menunggu**
Berikut dari contoh di atas, berikut ini adalah beberapa pseudo code dari bagaimana untuk menulis ini:
//ASYNCHRONOUS
//this is called every 5 seconds
async void CheckWeather()
{
var weather = await GetWeather();
//do something with the weather now you have it
}
async Task<WeatherResult> GetWeather()
{
var weatherJson = await CallToNetworkAddressToGetWeather();
return deserializeJson<weatherJson>(weatherJson);
}
//SYNCHRONOUS
//This method is called whenever the screen is pressed
void ScreenPressed()
{
DrawSketchOnScreen();
}
Tercepat untuk belajar..
Bagaimana dan Kapan untuk menggunakan <menyerang>
async
danmenunggu
</strike>tugas-Tugas
? Karena belajarTugas
secara otomatis meliputi 2 lainnya. Untuk kepentingan pembelajaran minimal. Tentu saja, ini adalah jawaban untuk pertanyaan anda tentangasync
danmenunggu
. Cepat mendapatkan melalui sintaks gula: 5 menit
internal static int Metode(int arg0, int arg1) { int hasil = arg0 + arg1; IO(); // Melakukan beberapa lama berjalan IO. return hasil; }
internal statis Tugas<int> MethodTask(int arg0, int arg1) { Tugas<int> tugas = Tugas baru<int>(() => Metode(arg0, arg1)); tugas.Start(); // Hot tugas (mulai tugas) harus selalu dikembalikan. kembali tugas; }
Apakah kita menyebutkan menanti atau async? No. Memanggil metode di atas dan anda mendapatkan sebuah tugas. Yang dapat anda monitor. Anda sudah tahu apa tugas kembali.. integer.
Panggilan Tugas adalah sedikit rumit. Mari kita sebut MethodTask()
internal statis async Task<int> MethodAsync(int arg0, int arg1) { int hasil = menunggu HelperMethods.MethodTask(arg0, arg1); return hasil; }
Kami adalah 'menunggu' tugas untuk diselesaikan. Maka menunggu
. Karena kita menggunakan menunggu, kita harus menggunakan async(wajib) dan MethodAsync dengan 'Async' sebagai awalan (coding standard). Lanjut membaca untuk kemudian di sini
Berbagi kebingungan pengembang: 5 menit
Pengembang telah membuat kesalahan dengan tidak melaksanakan Tugas
tapi itu masih bekerja! Cobalah untuk memahami pertanyaan dan jawaban yang diterima yang disediakan di sini. Harap anda telah membaca dan memahami sepenuhnya. Demikian juga dalam contoh kita memanggil aplikasi yang sudah dibangun MethodAsync()
adalah cara yang lebih mudah daripada menerapkan metode tersebut dengan Tugas
(MethodTask()
) diri mereka sendiri. Sebagian besar pengembang merasa sulit untuk mendapatkan kepala mereka di sekitar tugas-Tugas
saat mengkonversi kode Asinkron satu.
Tip: Cobalah untuk menemukan aplikasi yang ada Async pelaksanaan (seperti MethodAsync
atau ToListAsync
) untuk melakukan outsourcing kesulitan. Jadi kita hanya perlu berurusan dengan Async dan menunggu (yang lebih mudah dan cukup mirip dengan kode normal)
Masalah: dengan Cepat mengubah dunia nyata pelaksanaan kode normal untuk
Async operasi: 2 menit
Baris kode yang ditunjukkan di bawah ini di Lapisan Data mulai rusak(banyak tempat). Karena kami diperbarui beberapa kode dari .Net framework 4.2 untuk .Net inti. Kami harus memperbaiki hal ini dalam 1 jam seluruh aplikasi! var myContract = query.Where(c => c.ContractID == _contractID).First();
easypeasy!
var myContract = await query.Where(c => c.ContractID == _contractID).FirstAsync();
Kontrak GetContract(int contractnumber)
untuk
async Task<Kontrak> GetContractAsync(int contractnumber)
GetContractAsync(123456);
disebut sebagai GetContractAsync(123456).Hasil;
Pada tingkat yang lebih tinggi:
Async kata kunci memungkinkan menanti dan yang's semua itu. Kata kunci Async tidak menjalankan metode di thread terpisah. Awal f async metode berjalan serentak sampai hits menunggu pada tugas yang memakan waktu.
Anda dapat menginap pada metode yang mengembalikan Tugas atau Tugas dari jenis T. Anda tidak menunggu di async void method.
saat thread utama pertemuan menanti pada tugas yang memakan waktu atau ketika pekerjaan yang sebenarnya dimulai, thread utama kembali ke pemanggil saat ini metode.
Jika thread utama melihat menanti pada tugas yang masih melaksanakan, itu doesn't menunggu untuk itu dan kembali ke pemanggil saat ini metode. Dengan cara ini, aplikasi tetap responsif.
Menunggu pada pengolahan tugas, sekarang akan mengeksekusi pada sebuah thread terpisah dari benang kolam renang.
Saat ini menunggu tugas selesai, semua kode di bawah ini akan dieksekusi oleh thread terpisah
Di bawah ini adalah contoh kode. Melaksanakan dan memeriksa benang id
using System;
using System.Threading;
using System.Threading.Tasks;
namespace AsyncAwaitDemo
{
class Program
{
public static async void AsynchronousOperation()
{
Console.WriteLine("Inside AsynchronousOperation Before AsyncMethod, Thread Id: " + Thread.CurrentThread.ManagedThreadId);
//Task<int> _task = AsyncMethod();
int count = await AsyncMethod();
Console.WriteLine("Inside AsynchronousOperation After AsyncMethod Before Await, Thread Id: " + Thread.CurrentThread.ManagedThreadId);
//int count = await _task;
Console.WriteLine("Inside AsynchronousOperation After AsyncMethod After Await Before DependentMethod, Thread Id: " + Thread.CurrentThread.ManagedThreadId);
DependentMethod(count);
Console.WriteLine("Inside AsynchronousOperation After AsyncMethod After Await After DependentMethod, Thread Id: " + Thread.CurrentThread.ManagedThreadId);
}
public static async Task<int> AsyncMethod()
{
Console.WriteLine("Inside AsyncMethod, Thread Id: " + Thread.CurrentThread.ManagedThreadId);
int count = 0;
await Task.Run(() =>
{
Console.WriteLine("Executing a long running task which takes 10 seconds to complete, Thread Id: " + Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(20000);
count = 10;
});
Console.WriteLine("Completed AsyncMethod, Thread Id: " + Thread.CurrentThread.ManagedThreadId);
return count;
}
public static void DependentMethod(int count)
{
Console.WriteLine("Inside DependentMethod, Thread Id: " + Thread.CurrentThread.ManagedThreadId + ". Total count is " + count);
}
static void Main(string[] args)
{
Console.WriteLine("Started Main method, Thread Id: " + Thread.CurrentThread.ManagedThreadId);
AsynchronousOperation();
Console.WriteLine("Completed Main method, Thread Id: " + Thread.CurrentThread.ManagedThreadId);
Console.ReadKey();
}
}
}
public static void Main(string[] args)
{
string result = DownloadContentAsync().Result;
Console.ReadKey();
}
// You use the async keyword to mark a method for asynchronous operations.
// The "async" modifier simply starts synchronously the current thread.
// What it does is enable the method to be split into multiple pieces.
// The boundaries of these pieces are marked with the await keyword.
public static async Task<string> DownloadContentAsync()// By convention, the method name ends with "Async
{
using (HttpClient client = new HttpClient())
{
// When you use the await keyword, the compiler generates the code that checks if the asynchronous operation is finished.
// If it is already finished, the method continues to run synchronously.
// If not completed, the state machine will connect a continuation method that must be executed WHEN the Task is completed.
// Http request example.
// (In this example I can set the milliseconds after "sleep=")
String result = await client.GetStringAsync("http://httpstat.us/200?sleep=1000");
Console.WriteLine(result);
// After completing the result response, the state machine will continue to synchronously execute the other processes.
return result;
}
}
Cara yang saya mengerti juga, harus ada ketiga istilah ini ditambahkan ke campuran: Tugas
.
Async
adalah kualifikasi yang anda menempatkan pada anda metode untuk mengatakan itu's metode asynchronous.
Tugas
adalah kembalinya async
fungsi. Dijalankan secara asinkron.
Anda menunggu
Tugas. Ketika eksekusi kode mencapai garis ini, kontrol melompat keluar kembali ke pemanggil anda seputar fungsi semula.
Jika sebaliknya, anda menetapkan kembali dari sebuah async
fungsi (ie Tugas
) untuk variabel, ketika eksekusi kode mencapai garis ini, hanya terus lalu bahwa garis di sekitarnya fungsi sementara yang Tugas
mengeksekusi asynchronously.
menggunakan mereka sama dengan pemijahan latar belakang benang untuk melakukan long durasi logika?
Artikel ini MDSN:Asynchronous Pemrograman dengan async dan menunggu (C#) menjelaskan hal itu secara eksplisit:
async dan menunggu kata kunci don't menyebabkan tambahan benang dibuat. Async metode don't membutuhkan multithreading karena async metode doesn't berjalan di thread sendiri. Metode yang berjalan pada saat ini sinkronisasi konteks dan menggunakan waktu di thread hanya ketika metode aktif.
Dalam kode berikut, HttpClient metode GetByteArrayAsync kembali Tugas<byte[]>, getContentsTask. Tugas ini adalah janji untuk menghasilkan yang sebenarnya byte array ketika tugas selesai. Menunggu operator diterapkan untuk getContentsTask untuk menangguhkan eksekusi dalam SumPageSizesAsync sampai getContentsTask lebih lengkap. Sementara itu, kendali dikembalikan ke pemanggil SumPageSizesAsync. Ketika getContentsTask selesai, menunggu evaluasi ekspresi ke byte array.
private async Task SumPageSizesAsync()
{
// To use the HttpClient type in desktop apps, you must include a using directive and add a
// reference for the System.Net.Http namespace.
HttpClient client = new HttpClient();
// . . .
Task<byte[]> getContentsTask = client.GetByteArrayAsync(url);
byte[] urlContents = await getContentsTask;
// Equivalently, now that you see how it works, you can write the same thing in a single line.
//byte[] urlContents = await client.GetByteArrayAsync(url);
// . . .
}
Jawaban berikut ini adalah berguna sebagai panduan umum tentang menunggu/async. Mereka juga mengandung beberapa detail tentang bagaimana menanti/async adalah kabel. Saya ingin berbagi beberapa pengalaman praktis dengan anda yang harus anda ketahui sebelum menggunakan pola desain ini.
Istilah "menanti" adalah literal, sehingga benang apapun anda menyebutnya akan menunggu hasil dari metode ini sebelum melanjutkan. Pada depan thread, ini adalah bencana. Latar benang membawa beban membangun aplikasi anda, termasuk pemandangan, view model, awal animasi, dan apa pun yang anda telah boot-terikat dengan unsur-unsur. Jadi, ketika anda menunggu latar benang, anda stop aplikasi ini. Pengguna menunggu dan menunggu ketika tidak ada yang muncul untuk terjadi. Ini menyediakan negatif pengalaman pengguna.
Anda pasti bisa menunggu latar belakang benang menggunakan berbagai cara:
Device.BeginInvokeOnMainThread(async () => { await AnyAwaitableMethod(); });
// Notice that we do not await the following call,
// as that would tie it to the foreground thread.
try
{
Task.Run(async () => { await AnyAwaitableMethod(); });
}
catch
{}
Kode lengkap untuk pernyataan ini adalah di https://github.com/marcusts/xamarin-forms-annoyances. Lihat solusi yang disebut AwaitAsyncAntipattern.sln.
GitHub situs ini juga menyediakan link ke diskusi yang lebih rinci tentang topik ini.