Arka plan görevi tamamlandıktan sonra kullanıcı arayüzünü güncelleyemiyorum ASP.NET uygulama

0

Soru

Uzun süredir çalışan bir işlevi arka plan görevi olarak çalıştırıyorum. asp.net başvuru. Görev tamamlanmadan önce ana iş parçacığı çıkar (yalnızca bu şekilde olmasını istiyorum, çünkü await anahtar kelimesini kullanırsam ve ana iş parçacığının arka plan görevi tamamlanana kadar beklemesini sağlarsam, mesajla proxy hatası alıyorum

Proxy Hatası
Proxy sunucusu, arka plan görevi çok uzun olduğu için yukarı akış sunucusundan geçersiz bir yanıt aldı

Ancak görev tamamlandıktan sonra ne aynı sayfaya yönlendirerek sayfayı yenileyebiliyorum ne de kullanıcı arayüzünü geçersiz kılabiliyorum. Ana iş parçacığı yürütmeyi tamamladıktan sonra kullanıcı arayüzünü güncellemenin herhangi bir yolu var mı?

Kodum şöyle:

protected void btnImport_Click(object sender, EventArgs e)
{
        var task = ImportThread();

        if (task.IsCompleted)
        {
            DisplaySuccess("Import success");
        }
        else
            DisplayError("Import failed");
}

private async Task<bool> ImportThread()
{
        try
        {
            var success = await Task<bool>.Run(() => new Manager().Import().ConfigureAwait(false);

            if (task.IsCompleted)
            {
                DisplaySuccess("Import success");
            }
            else 
            {
                DisplayError("Import failed");
            }
    
            return true;
}

Yukarıdaki zaman uyumsuz görev, aşağıda başka bir sınıfta bulunan yöntemi beklemektedir.

public bool Import()
{
    // some operations here
    return true;
}

Bu yöntem tamamlandıktan sonra denetim geri döner ImportThread() ancak Uı'yi geçersiz kılmak için orada yazılan kod uı'yi güncellemiyor. Kullanıcı arayüzünü içe aktarma durumuyla güncellemem gerekiyor. Ve aynı zamanda ImportThread denetim, düğme tıklatma olayı yöntemine de geri dönmüyor.

İthalat UI durum Güncellemesi için herhangi bir şekilde bana yardım et lütfen.

Not: Kullanmayı denedim Redirect.Response içinde ImportThread() sayfayı yenilemek için, ancak bu işe yaramadı

asp.net async-await background-task c#
2021-11-23 19:55:22
2

En iyi cevabı

1

Sorununuz, burada web sayfası yaşam döngüsünü kavramanız ve altında durmanız gerektiğidir.

Web sayfasının kullanıcıların masaüstünde oturduğu bu durum var:

enter image description here

Şimdi kullanıcının bir düğmeyi tıklattığını söyleyin.

Şimdi bu var :

 var task = ImportThread();

    if (task.IsCompleted)

Tamam, yani web sayfası sunucuda. İnekler eve gelene kadar eşzamansız beklemeler bile koyabilirsiniz, ama yine de BUNA sahipsiniz:

enter image description here

Bu nedenle, kodunuz çalıştığı veya beklediği sürece, web sayfası hala sunucu tarafında sıkışmış durumdadır. YALNIZCA kod tamamlanıp çıkılana kadar sayfa istemci tarafına gider.

tekrar: Olamaz dur arkasında, ve kod bitirmek için, yana eğer bir şey için sabırsızlanıyorum, sonra sayfayı sunucuda bitmiş işleme kadar KALIR.

SONRA VE ANCAK O zaman web sayfası istemci tarafına geri yolculuk yapar. Bu daha sonra gerçekleşir;

enter image description here

Ve sonra SUNUCU TARAFI SAYFASI bellekten atılır ve tüm sınıf değişkenleri yok edilir!!! Web sunucusu artık herhangi bir kullanıcının işlenmek üzere bir sayfayı geri göndermesini bekliyor!!

Yani, uzun süren bir süreç yürütmeniz gerekiyorsa?

Birkaç seçenek var :

sayfayı yayınlayın, arkasındaki kod çalışır, arkasındaki kod YENİ bir iş parçacığı başlatır, web sayfası istemci tarafına geri döner. Bu noktada, uzun süren işlemin tamamlanıp tamamlanmadığını sorgulamak veya sunucuya sormak için bir zamanlayıcı + bir tür web yöntemi çağrısı (ajax) gerekir. Ve bir ajax çağrısı, o sayfada veya sayfa sınıfı değişkenlerinde herhangi bir web denetimi kullanmadığından (unutmayın, web sayfası istemci tarafına geri döndükten sonra, web sayfası bellekte mevcut web sunucusu tarafı değildir veya sınıf değişkenlerinden herhangi biri mevcut değildir). Yani, yine, bu oldukça fazla bir çeşit zamanlayıcı veya belirtildiği gibi, bazı ajax yöntemlerini çağırmak için bir zamanlayıcı + kodu anlamına gelir. denetimleri ve hatta viewstate'i kullanmadığınız için bu uzun süren işlemin BÜYÜK olasılıkla session () kullanması gerekecektir.

Ajax çağrısı kullanmanıza da gerek yok. Her 1 veya 2 saniyede bir düğmeyi tıklattığını söyleyen bir zamanlayıcı ile basit bir JavaScript istemci tarafı rutini kullanabilirsiniz, arkasındaki kod çalışır ve daha sonra bu uzun süren işlemin durumunu alması gerekir (yine muhtemelen oturumdan) ve ardından ekranı güncelleyin. Ve sonra durum "bitti" ya da her neyse değiştiğinde zamanlayıcıyı durdurmak için kod da ekleyebilirsiniz.

Bu nedenle, arkasındaki kod web sayfasını birden çok kez" güncellemez " ve "güncellemez". Bir gidiş dönüşünüz var ve arkasındaki kod hızlı çalışmalı, çalışmayı bitirmeli ve bir AWAİT komutunu bile kullanamıyor, o zamandan beri sayfa bekleyecek ve hala sunucuda sıkışmış olacak.

Sık sık kullandığım basit zamanlayıcı hilesi yaklaşımının ötesine geçmek istiyorsanız?

Ardından, web sitenize bu tür bir durum için tasarlanmış bir şeyi benimsemeniz ve tanıtmanız gerekir -

Neyse ki, bu amaç için SignalR var ve şüphesiz sizin için en iyi seçenek ve yaklaşım, çünkü tam olarak sorunuz ve senaryonuz için tasarlandı.

SinyalR

https://docs.microsoft.com/en-us/aspnet/signalr/overview/getting-started/introduction-to-signalr#:~:text=20ASP What%20is%20SignalR%3F%.NET%20SignalR%20is%20a%20library,process%20of%20adding%20real-time%20web%20functionality%20to%20applications.

2021-11-23 21:28:35
0

Bir kullanıcıyı eşzamansız olarak (görev gibi herhangi bir şeyin tamamlandığını veya başarısız olduğunu) bildirmek istiyorsanız, web push bildirimini (firebase messaging cloud kullanarak) veya SignalR soketlerini kullanabilirsiniz. Bir arka plan görevi kullandığınızda, ana iş parçacığını kaybedersiniz ve maalesef ilgili kullanıcıya yanıt vermenin bir yolu yoktur.

2021-11-23 20:31:11

Diğer dillerde

Bu sayfa diğer dillerde

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................