Rumah >pembangunan bahagian belakang >C++ >Bagaimanakah Penjujukan Tugasan Boleh Dikekalkan dengan Kemasukan Semula dalam Operasi Asynchronous?

Bagaimanakah Penjujukan Tugasan Boleh Dikekalkan dengan Kemasukan Semula dalam Operasi Asynchronous?

Susan Sarandon
Susan Sarandonasal
2024-12-28 17:02:15870semak imbas

How Can Task Sequencing Be Maintained with Re-Entrancy in Asynchronous Operations?

Penjujukan Tugasan dan Kemasukan Semula

Dalam senario di mana tugasan boleh sampai lebih cepat daripada yang diproses dan mungkin bergantung pada hasil sebelumnya, penjujukan tugas menjadi penting. Cabaran ini ditambah apabila kemasukan semula diperlukan.

Pernyataan Masalah

Pengendali arahan UI boleh memproses arahan secara serentak atau tidak segerak. Arahan boleh tiba pada kadar yang melebihi kelajuan pemprosesan, memerlukan beratur dan pemprosesan berurutan. Setiap hasil tugasan baharu mungkin bergantung pada pendahulunya. Walaupun pembatalan dikecualikan untuk kesederhanaan, kemasukan semula mesti disokong.

Pendekatan Awal

Dalam apl konsol asas, kelas AsyncOp mengurus penjujukan tugas. Setiap tugasan dianggap sebagai kesinambungan daripada tugasan sebelumnya, memastikan kebergantungan dipenuhi. Walau bagaimanapun, apabila kemasukan semula diperkenalkan, logiknya rosak.

Penyelesaian Disegerakkan

Untuk menangani isu ini, tugasan dibina secara manual tanpa menjadualkannya pada mulanya. Sebaliknya, "Task.Factory.StartNew" digunakan untuk menjalankan tugasan secara serentak, menghalangnya daripada melaksanakan sehingga tugas pembungkus siap. Ini memastikan urutan itu dikekalkan.

Pelaksanaan Kod

class AsyncOp<T>
{
    Task<T> _pending = Task.FromResult(default(T));

    public Task<T> CurrentTask => _pending;

    public Task<T> RunAsync(Func<Task<T>> handler, bool useSynchronizationContext = false)
    {
        var pending = _pending;
        var wrapper = async () =>
        {
            var prevResult = await pending;
            Console.WriteLine($"\nprev task result:  {prevResult}");
            return await handler();
        };

        var task = new Task<Task<T>>(wrapper);
        var inner = task.Unwrap();
        _pending = inner;

        task.RunSynchronously(useSynchronizationContext ?
            TaskScheduler.FromCurrentSynchronizationContext() :
            TaskScheduler.Current);

        return inner;
    }
}

Output Kemas Kini

Test #1...

prev task result:  0
this task arg: 1000

prev task result:  1000
this task arg: 900

prev task result:  900
this task arg: 800

Press any key to continue to test #2...


prev task result:  800
this task arg: 100

prev task result:  100
this task arg: 200

Pelanjutan

Pendekatan ini membolehkan penambahbaikan tambahan seperti sebagai keselamatan benang dengan melaksanakan kunci untuk melindungi keadaan dikongsi. Selain itu, logik batal/mulakan semula boleh digabungkan untuk menangani gangguan tugas.

Atas ialah kandungan terperinci Bagaimanakah Penjujukan Tugasan Boleh Dikekalkan dengan Kemasukan Semula dalam Operasi Asynchronous?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn