Çıktımı görüntüledikten sonra konsol penceresi neden hemen kapanıyor?


158

Ben kılavuzları takip ederek C # okuyorum MSDN .

Şimdi, Örnek 1'i denedim ( burada MSDN bağlantısı var ) ve bir sorunla karşılaştım: konsol penceresi çıkışımı görüntülediğinde neden hemen kapanıyor?

using System;

public class Hello1
{
    public static int Main()
    {
        Console.WriteLine("Hello, World!");
        return 0;
    }
}

Konsolla açmayı deneyebilirsiniz. Konsola sürükleyip bırakın ve "Enter" tuşuna basın. Bir EXE dosyası olduğunu varsayalım.
Sajidur Rahman

Harici bir işlem tarafından başlatılan bir komut satırı programını DEBUG yapmaya çalışıyorsanız, şu soruya bakın: stackoverflow.com/a/23334014/3195477
UuDdLrLrSs 26:18

Yanıtlar:


267

Buradaki sorun, Merhaba Dünya Programının ortaya çıkması ve hemen kapanmasıdır.
Neden?

Çünkü bitti. Konsol uygulamaları yürütmeyi tamamladığında ve mainyöntemlerinden döndüklerinde , ilişkili konsol penceresi otomatik olarak kapanır. Bu beklenen davranıştır.

Hata ayıklama amacıyla açık tutmak istiyorsanız, uygulamayı sonlandırmadan ve pencereyi kapatmadan önce bilgisayara tuşa basmayı beklemesi talimatını vermeniz gerekir.

Console.ReadLineYöntem Bunu yapmanın bir yoludur. Bu satırı kodunuzun sonuna ( returnifadeden hemen önce ) eklemek, uygulamanın çıkmadan önce bir tuşa basmanızı beklemesine neden olur.

Alternatif olarak, uygulamayı Visual Studio ortamından Ctrl+ düğmesine basarak hata ayıklayıcıyı eklemeden başlatabilirsiniz F5, ancak bunun, bir uygulama yazarken muhtemelen kullanmak istediğiniz hata ayıklama özelliklerini kullanmanızı engellemenin bariz dezavantajı vardır.

En iyi uzlaşma, Console.ReadLineyöntemi yalnızca uygulamada bir önişlemci yönergesine sararak hata ayıklarken çağırmaktır . Gibi bir şey:

#if DEBUG
    Console.WriteLine("Press enter to close...");
    Console.ReadLine();
#endif

Yakalanmayan bir istisna atılırsa pencerenin açık kalmasını da isteyebilirsiniz. Bunu yapmak için Console.ReadLine();bir finallybloğa koyabilirsiniz :

#if DEBUG
    try
    {
        //...
    }
    finally
    {
        Console.WriteLine("Press enter to close...");
        Console.ReadLine();
    }
#endif

18
Alternatif olarak, Console.ReadKey ();
PlantationGator

55
Şahsen ben tercih ederim if (System.Diagnostics.Debugger.IsAttached) Console.ReadLine();.
Sameer Singh

5
Hata ayıklamadan çalıştırma neden bu davranışı değiştirir? Bunun daha az değil, daha doğru bir deneyim olması gerektiğini düşünürdünüz.
Kyle Delaney

@SameerSingh İkili dosyaya derlenmekte olan bir kod daha. Aslında bu önişlemci yaklaşımını tercih ediyorum.
Joel

@Joel Bugünlerde bunu neden önemsemeliyiz?
Alex

66

Kullanmak yerine

Console.Readline()
Console.Read()
Console.ReadKey()

programınızı Ctrl+ kullanarak çalıştırabilirsiniz F5(Visual Studio'daysanız). Daha sonra Visual Studio, siz bir tuşa basıncaya kadar konsol penceresini açık tutacaktır.

Not: Kodunuzda bu yaklaşımda hata ayıklayamazsınız.


Merhaba kullanıcı. Genel olarak VS ve C # için yeni bir kullanıcıyım. Ctrl + F5Farklı olan basitçe farklı olan ne yapar Start?
theGreenCabbage

ne yazık ki, bazen beklendiği gibi çalışmayı durdurur.
MaikoID

2
Sorunun nedeni, program durduğunda pencerelerin terminal penceresini otomatik olarak kapatmasıdır. Diğer sistemler Pencereyi otomatik olarak açık tutacaktır. Programı çalıştırmanın en iyi yolu budur. Bu program için ReadKey, Read veya ReadLine kullanmayın; bu, programınızın diğer konsol uygulamaları ve borularla birlikte kullanılmasını önler.
gerçek zamanlı

14

Ben hata ayıklama modunda kapatmak istemiyorum nedeni, çünkü değişkenlerin değerlerine bakmak istiyorum çünkü bu yüzden muhtemelen en iyi ana işlevi kapanış "}" kapatma noktası eklemek en iyisidir . Hata ayıklamanız gerekmiyorsa, Ctrl-F5 en iyi seçenektir.


Diğer cevapların hiçbiri bunu şaşırtmadı. Soru oluşturulduktan sonra çok geç eklenen yeni bir seçeneğe sahip bir cevap nadirdir.
Scott Chamberlain

13

Bu CtrlF5veya için aynı şekilde davranır F5. MainYöntemin bitiminden hemen önce yerleştirin .

using System.Diagnostics;

private static void Main(string[] args) {

  DoWork();

  if (Debugger.IsAttached) {
    Console.WriteLine("Press any key to continue . . .");
    Console.ReadLine();
  }
}

7
Sadece not etmek için, son satır Console.ReadKey()herhangi bir anahtar için olmalı , Console.ReadLine()enter tuşuna basılmasını bekliyor
Chris

6

Program hemen kapanıyor çünkü kapanmasını engelleyen bir şey yok. Programın kapanmasını önlemek için bir kesme noktası return 0;ekleyin veya daha Console.Read();önce ekleyin return 0;.


5

Partiye biraz geç kaldım, ancak: .NET Core projeleri için Visual Studio 2019'da konsol varsayılan olarak otomatik olarak kapanmıyor. Davranışı Araçlar → Seçenekler → Hata Ayıklama → Genel → Hata ayıklama durduğunda konsolu otomatik olarak kapatarak yapılandırabilirsiniz. Konsol pencerenizi otomatik olarak kapatırsanız, belirtilen ayarın ayarlanmadığını kontrol edin.

Aynısı .NET Framework yeni stil konsolu projeleri için de geçerlidir:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net472</TargetFramework>
  </PropertyGroup>

</Project>

Eski stil .NET Framework projesi yine de koşulsuz olarak konsolu kapatıyor (Visual Studio 16.0.1'den itibaren).

Referans: https://devblogs.microsoft.com/dotnet/net-core-tooling-update-for-visual-studio-2019-preview-2/


Bu seçenek VS2017 15.9.4'te benim için kullanılabilir, ancak .net core 2.1 konsol uygulaması için çalışmıyor ...
user1073075

@ user1073075: bu garip. Özellik diğer hedefler için çalışıyor mu?
Vlad

Hayır. Bir .NET framework konsol uygulaması ile denendi ve hala çalışmadı. (VS2019'u farklı bir makineye kurdum ve işe yarıyor. Belki VS17'de bir hata 15.9.4)
user1073075

2019 ile şimdi WPF projeleri için bile çalışıyor: pastebin.com/FpAeV0cW . Ancak .NET Core 3'ü yüklemelisiniz.
Vlad

5

Başvurunuzu açık tutmak istiyorsanız, sürecini canlı tutmak için bir şeyler yapmanız gerekir. Aşağıdaki örnek, programınızın sonuna yerleştirilecek en basit örnektir:

while (true) ;

Ancak, CPU'nun aşırı yüklenmesine neden olur, çünkü bu nedenle sonsuz bir şekilde tekrarlamak zorunda kalır.

Bu noktada, System.Windows.Forms.Applicationsınıfı kullanmayı tercih edebilirsiniz (ancak System.Windows.Formsreferans eklemenizi gerektirir ):

Application.Run();

Bu CPU sızdırmaz ve başarılı bir şekilde çalışır.

Eklemek kaçınmak amacıyla System.Windows.Formsreferans, basit bir hile, sözde kullanabilir sıkma bekleme ithal System.Threading:

SpinWait.SpinUntil(() => false);

Bu da mükemmel bir şekilde çalışır ve temel whileolarak yukarıdaki lambda yöntemiyle döndürülen olumsuzlanmış bir koşula sahip bir döngüden oluşur . Bu aşırı CPU neden olmasın? Kaynak koduna buradan bakabilirsiniz ; neyse, temelde tekrar etmeden önce bazı CPU döngüsünü bekler.

Ayrıca, bekleyen mesajları sistemden izleyen ve bir sonraki yinelemeye geçmeden önce her birini işleyen bir mesaj lüper oluşturabilirsiniz:

[DebuggerHidden, DebuggerStepperBoundary, DebuggerNonUserCode, DllImport("user32.dll", EntryPoint = "PeekMessage")]
public static extern int PeekMessage(out NativeMessage lpMsg, IntPtr hWnd, int wMsgFilterMin, int wMsgFilterMax, int wRemoveMsg);

[DebuggerHidden, DebuggerStepperBoundary, DebuggerNonUserCode, DllImport("user32.dll", EntryPoint = "GetMessage")]
public static extern int GetMessage(out NativeMessage lpMsg, IntPtr hWnd, int wMsgFilterMin, int wMsgFilterMax);

[DebuggerHidden, DebuggerStepperBoundary, DebuggerNonUserCode, DllImport("user32.dll", EntryPoint = "TranslateMessage")]
public static extern int TranslateMessage(ref NativeMessage lpMsg);

[DebuggerHidden, DebuggerStepperBoundary, DebuggerNonUserCode, DllImport("user32.dll", EntryPoint = "DispatchMessage")]
public static extern int DispatchMessage(ref NativeMessage lpMsg);

[DebuggerHidden, DebuggerStepperBoundary, DebuggerNonUserCode]
public static bool ProcessMessageOnce()
{
    NativeMessage message = new NativeMessage();

    if (!IsMessagePending(out message))
        return true;

    if (GetMessage(out message, IntPtr.Zero, 0, 0) == -1)
        return true;

    Message frameworkMessage = new Message()
    {
        HWnd = message.handle,
        LParam = message.lParam,
        WParam = message.wParam,
        Msg = (int)message.msg
    };

    if (Application.FilterMessage(ref frameworkMessage))
        return true;

    TranslateMessage(ref message);
    DispatchMessage(ref message);

    return false;
}

Ardından, böyle bir şey yaparak güvenli bir şekilde döngü yapabilirsiniz:

while (true)
    ProcessMessageOnce();

Bu CPU sızıntısı olup olmadığını bilmiyorum ama; başarıyla çalışıyor. Teşekkür ederim.
Mumin Ka

4

Alternatif olarak, aşağıdaki kodu kullanarak kapanmayı geciktirebilirsiniz:

System.Threading.Thread.Sleep(1000);

SleepMilisaniye kullandığını unutmayın .


4

Başka bir yol Debugger.Break()Main yönteminden dönmeden önce kullanmaktır


Bu anahtarlar hata ayıklayıcı penceresine odaklanır ve konsol penceresinin içeriğini gizler.
Stephen Turner

3

Kod bitti, devam etmek için şunu eklemeniz gerekiyor:

Console.ReadLine();

veya

Console.Read();

3

Console.Read () kullanın; programın kapanmasını önlemek için, ancak Console.Read();kodu return ifadesinden önce eklediğinizden emin olun , aksi takdirde erişilemez bir kod olacaktır.

    Console.Read(); 
    return 0; 

bu Konsolu kontrol edin.


3

Ekle ReadÇıktıyı gösterme yöntemi.

Console.WriteLine("Hello, World!");
Console.Read();
return 0;

1

İşte bunu içermeden yapmanın bir yolu Console:

var endlessTask = new TaskCompletionSource<bool>().Task;
endlessTask.Wait();

0

Program, yürütme işlemi tamamlanır tamamlanmaz kapanıyor. Bu durumda siz return 0;. Bu beklenen bir işlevdir. Çıktıyı görmek istiyorsanız, ya bir terminalde manuel olarak çalıştırın ya da programın sonunda birkaç saniye açık kalacak şekilde (iplik kitaplığı kullanarak) bekleyin.


0

Bu C # konsol uygulamasında cevap async olduğunu?

konsol uygulamasındaki hiçbir yerde asla awaitkullanmamak theAsyncMethod().GetAwaiter().GetResult();, kullanmak yerine ,

misal

var result = await HttpClientInstance.SendAsync(message);

olur

var result = HttpClientInstance.SendAsync(message).GetAwaiter().GetResult();


-3

programınız, bir değer girip devam etmeniz gibi devam etmek için enter tuşuna basmanızı gerektiriyorsa, yeni bir çift veya int ekleyin ve retunr (0) 'dan önce write yazın; scanf_s ("% lf" ve değişken);


1
Bu bir C # sorusudur.
Wai Ha Lee

-3

Her zaman bir konsol uygulamasına aşağıdaki ifadeyi ekliyorum. (İsterseniz bunun için bir kod snippet'i oluşturun)

Console.WriteLine("Press any key to quit!");
Console.ReadKey();

Bunu yapmak, konsol uygulaması aracılığıyla farklı kavramları denemek istediğinizde yardımcı olur.

Ctr + F5 , Konsolun kalmasını sağlayacak ama hata ayıklayamazsınız! Realworld'de yazdığım tüm konsol uygulamaları her zaman etkileşimli değildir ve TWS veya CA Work station gibi bir Zamanlayıcı tarafından tetiklenir ve böyle bir şey gerektirmez.


-3

Başkalarının söylediklerini basitleştirmek için: Kullanın Console.ReadKey();.

Bu, programın kullanıcının klavyedeki normal bir tuşa basmasını beklemesini sağlar.

Kaynak: Konsol uygulamaları için programlarımda kullanıyorum.


-3

Sadece girdiyi çağırmak çok basit bir şekilde çözebilirsiniz. Ancak, düğmesine basarsanız Enterkonsol tekrar düşecektir. Bunu kullanın Console.ReadLine();veyaConsole.Read();


-4

Dönüş 0'dan önce aşağıdakileri ekleyin:

system("PAUSE");  

Bu, pencereyi kapatmak için bir tuşa basmak için bir satır yazdırır. Enter tuşuna basana kadar pencereyi yukarıda tutacaktır. Öğrencilerimin tüm programlarına eklemesini istiyorum.


1
şu c ++ 'da
Gonçalo Garrido

-13

Endişeme göre, KONSOL UYGULAMA ÇIKIŞINI sabitlemek istiyorsak, çıkış ekranı KULLANIMI, etiket: MainMethod ve goto etiketinden sonra; program bitmeden

Programda.

Örneğin:

static void Main(string[] args)
{
    label:

    // Snippet of code

    goto label;
}

2
Bu sadece poster programı "Merhaba, Dünya!" birçok kez
DavidPostill

1
İsa Mesih, gotoC # 'da bile ifadeye izin verildiğini bilmiyordu .
Ch3shire
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.