C# Top-level Statements WPF ์‹คํ–‰ ๋ฐฉ๋ฒ•?

์•ˆ๋…•ํ•˜์„ธ์š”. :smile:

C# 9.0 ๊ธฐ๋Šฅ์ธ Top-level Statements์— ๋Œ€ํ•ด ์•Œ์•„๋ณด๊ณ  ์žˆ๋Š”๋ฐ์š”.

ํ˜น์‹œ WPF๋„ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์„๊นŒ์š”?


Console์˜ ๊ฒฝ์šฐ์—๋Š” ์ž˜ ๋™์ž‘ํ•˜๋Š” ๊ฒƒ์„ ํ™•์ธํ–ˆ์Šต๋‹ˆ๋‹ค.

using System;

Console.WriteLine("Hello");
Console.WriteLine(args);

๊ทธ๋ž˜์„œ ์ด์™€ ๋น„์Šทํ•˜๊ฒŒ WPF๋„ ์‘์šฉํ•ด๋ณด์•˜์Šต๋‹ˆ๋‹ค.

using System;

Application app = new Application();
app.Startup += (s, e) => new Window().Show();
app.Run();

์•ฑ์„ ์‹คํ–‰ํ•˜๋ฉด [STAThread] ๊ด€๋ จ ์—๋Ÿฌ๊ฐ€ ๋‚ฉ๋‹ˆ๋‹ค.

๋งŽ์€ UI ๊ตฌ์„ฑ ์š”์†Œ์—์„œ ํ˜ธ์ถœ ์Šค๋ ˆ๋“œ๊ฐ€ ํ•„์š”ํ•˜๋ฏ€๋กœโ€ฆ


๊ทธ๋ž˜์„œ [STAThread]๋„ ์ถ”๊ฐ€ํ•ด๋ดค์Šต๋‹ˆ๋‹ค.

using System;

[STAThread]
void WpfStart()
{
    Application app = new Application();
    app.Startup += (s, e) => new Window().Show();
    app.Run();
}
WpfStart();

์ด๋ ‡๊ฒŒ๋„ ํ•ด๋ดค์ง€๋งŒ ๋™์ผํ•œ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒ๋ฉ๋‹ˆ๋‹ค.

ํ˜น์‹œ ์ œ๊ฐ€ ์ž˜๋ชป ์‚ฌ์šฉํ•œ ๋ถ€๋ถ„์ด ์žˆ์„๊นŒ์š”? ๊ทธ๋ฆฌ๊ณ  ์ด ๊ธฐ๋Šฅ์ด ์–ด๋–ค ์˜๋„๋กœ ์‚ฌ์šฉ๋˜์•ผ ํ•˜๋Š”์ง€๋„ ๊ถ๊ธˆํ•ฉ๋‹ˆ๋‹ค!

์ฝ์–ด์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค.

2๊ฐœ์˜ ์ข‹์•„์š”

Top-level Statements๋Š” attribute๋ฅผ ์“ธ ์ˆ˜ ์—†๋Š” ๊ฒƒ์œผ๋กœ ํ™•์ธ๋ฉ๋‹ˆ๋‹ค. TLS๋Š” ์ฒ˜์Œ C# ์„ ์ ‘ํ•˜๋Š” ์‚ฌ๋žŒ์ด ์–ธ์–ด๋ฅผ ์ ‘๊ทผํ•˜๊ธฐ ์‰ฝ๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•œ ๋ชฉ์ ์ด ์žˆ์–ด์„œ ๊ทธ๋Ÿฐ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

2๊ฐœ์˜ ์ข‹์•„์š”

์–ด์ฉ” ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์ง์ ‘ ํ•ด์ค˜์•ผ์ฃ . ^^; ์•„๋ž˜์˜ ๊ธ€์— ๊ด€๋ จ ๋‹ต๋ณ€์ด ์žˆ์Šต๋‹ˆ๋‹ค.

[c# 9.0 - How to handle {STAThread] in C# 9 Using Top-Level Program.cs - Stack Overflow](c# 9.0 - How to handle {STAThread] in C# 9 Using Top-Level Program.cs - Stack Overflow)

ํ˜น์€ ์ข€ ๋” ๋ณต์žกํ•˜์ง€๋งŒ ์•„๋ž˜์˜ ๊ธ€์— ์žˆ๋Š” StartSTATask ๋ฉ”์„œ๋“œ๋ฅผ ์ด์šฉํ•ด,

c# - Set ApartmentState on a Task - Stack Overflow

๋‹ค์Œ๊ณผ ๊ฐ™์€ ์‹์œผ๋กœ ์ฝ”๋”ฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

using System;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;

await StartSTATask(() =>
{
    Application app = new Application();
    app.Startup += (s, e) => new Window().Show();
    app.Run();

    return 0;
});

static Task<T> StartSTATask<T>(Func<T> func)
{
    var tcs = new TaskCompletionSource<T>();
    Thread thread = new Thread(() =>
    {
        try
        {
            tcs.SetResult(func());
        }
        catch (Exception e)
        {
            tcs.SetException(e);
        }
    });

    thread.SetApartmentState(ApartmentState.STA);
    thread.Start();
    return tcs.Task;
}
4๊ฐœ์˜ ์ข‹์•„์š”

๋น„์Šทํ•œ ์ด์œ ๋กœ Windows Forms ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜๋„ TLP ๊ธฐ๋Šฅ์œผ๋กœ ์ฝ”๋“œ๋ฅผ ์‹œ์ž‘ํ•  ์ˆ˜ ์—†๊ณ , ์•ž์˜ ๋ถ„๋“ค์ด ๋‹ต๊ธ€์„ ๋‹ฌ์•„์ฃผ์‹  ๊ฒƒ์ฒ˜๋Ÿผ workaround๋ฅผ ์ž…ํ˜€์•ผ ํ•˜๋Š”๋ฐ โ€œ๊ตณ์ด?โ€ ์‹ถ์€ ๋ถ€๋ถ„์ด ์ƒ๊ธฐ๋Š” ๊ฒƒ ๊ฐ™์•„์š”. ใ…Žใ…Ž

2๊ฐœ์˜ ์ข‹์•„์š”

์•„, ๊ทธ๋ฆฌ๊ณ  ์ด์ œ WPF์— ๊ด€๋ จ๋œ ๋‚ด์šฉ์€ ์œˆ๋„์šฐ ๋ฐ์Šคํฌํ†ฑ Q&A ์ชฝ์œผ๋กœ ์˜ฌ๋ ค์ฃผ์‹œ๋ฉด ๋” ์ข‹์„ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค! @jamesnet214

2๊ฐœ์˜ ์ข‹์•„์š”
Thread.CurrentThread.SetApartmentState(ApartmentState.Unknown);
Thread.CurrentThread.SetApartmentState(ApartmentState.STA);

๋ฅผ ํ†ตํ•ด ์ตœ์ƒ์œ„๋ฌธ์—์„œ [STAThread] ํšจ๊ณผ๋ฅผ ์ค„ ์ˆ˜ ์žˆ๋‹ค๊ณ  ํ•ฉ๋‹ˆ๋‹คโ€ฆ ์Œ ํ™•์ธํ•ด๋ดค๋”๋‹ˆ ๋˜๋„ค์š”.

2๊ฐœ์˜ ์ข‹์•„์š”