Signalr: async/await๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ฝ˜์†” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ ์ „์†ก ํ›„ ์ˆ˜์‹ ์„ ์ค‘์ง€ํ•ฉ๋‹ˆ๋‹ค.

์— ๋งŒ๋“  2017๋…„ 03์›” 22์ผ  ยท  4์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: SignalR/SignalR

๋‚˜๋Š” ๋ฉ”์‹œ์ง€๋ฅผ ๋ณด๋‚ด๊ณ  ๋ฐ›๊ธฐ ์œ„ํ•ด ํ•œ ์Œ์˜ ์ฝ˜์†” ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์„ ์‚ฌ์šฉํ•˜์—ฌ ์ŠคํŒŒ์ดํฌ ์ž‘์—…์„ ํ•˜๊ณ  ์žˆ์—ˆ๊ณ  ์•ฝ๊ฐ„์˜ ์ด์ƒํ•œ ๋™์ž‘์ด ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ตฌ๋…์ž ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์—์„œ await ์‚ฌ์šฉํ•˜์—ฌ ํ—ˆ๋ธŒ์—์„œ ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ์ƒˆ ๋ฉ”์‹œ์ง€ ์ˆ˜์‹ ์ด ์ค‘์ง€๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ฒ˜์Œ์— ์ด๊ฒƒ์€ Subscribe ๋ฉ”์†Œ๋“œ๋ฅผ ์ฆ‰์‹œ ํ˜ธ์ถœํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ฉ”์‹œ์ง€๋ฅผ ๋ฐ›์ง€ ๋ชปํ–ˆ๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ–ˆ์ง€๋งŒ, ์ž์„ธํžˆ ์‚ดํŽด๋ณด๋‹ˆ ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ๊นŒ์ง€ _ํ–‰๋ณตํ•˜๊ฒŒ ์ˆ˜์‹ ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋ฉ”์†Œ๋“œ๊ฐ€ ํ˜ธ์ถœ ๋  ๋•Œ .Wait() ๋Œ€์‹  await ๋ชจ๋“  ๊ดœ์ฐฎ์Šต๋‹ˆ๋‹ค.

์ด๊ฒƒ์ด ์ฝ˜์†” ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์—์„œ ์Šค๋ ˆ๋“œ๊ฐ€ ์ฒ˜๋ฆฌ๋˜๋Š” ๋ฐฉ์‹๊ณผ ๊ด€๋ จ์ด ์žˆ๋Š”์ง€( SynchronizationContext ์žˆ๋Š” WPF ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ๊ณผ ๋ฐ˜๋Œ€) ์•„๋‹ˆ๋ฉด C# SignalR ํด๋ผ์ด์–ธํŠธ์˜ ๋ฌธ์ œ์ธ์ง€ ์ž˜ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค.

์˜ˆ์ƒ๋˜๋Š” ํ–‰๋™

await hubProxy.Invoke("Foo"); ์„(๋ฅผ) ๋ฐ›๊ณ  ๋ฉ”์‹œ์ง€๋ฅผ ๊ณ„์† ๋ฐ›์„ ์ˆ˜ ์žˆ์„ ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒ๋ฉ๋‹ˆ๋‹ค.

์‹ค์ œ ํ–‰๋™

await hubProxy.Invoke("Foo"); ํ•˜๋ฉด ์—ฐ๊ฒฐ์ด ๋Š์–ด์ง‘๋‹ˆ๋‹ค.

์žฌํ˜„ ๋‹จ๊ณ„

```c#
์ˆ˜์—… ํ”„๋กœ๊ทธ๋žจ
{
์ •์  ๋ฌดํšจ Main()
{
์‹คํ–‰().๋Œ€๊ธฐ();
}

์ •์  ๋น„๋™๊ธฐ ์ž‘์—… ์‹คํ–‰()
{
Console.WriteLine("[๊ตฌ๋…์ž] ์ž…๋ ฅํ•˜๋ ค๋ฉด Enter ํ‚ค๋ฅผ ๋ˆ„๋ฅด์‹ญ์‹œ์˜ค...");
Console.ReadLine();

var hubConnection = new HubConnection("http://localhost:39103/");
var hubProxy = hubConnection.CreateHubProxy("MyHub");
hubProxy.On<string>("OnMessage", msg =>
{
  Console.WriteLine($"Received: {msg}");
});

await hubConnection.Start();

// Receiving messages quite happily at this point

Console.WriteLine("And press Enter again to break the application...");
Console.ReadLine();

await hubProxy.Invoke("Foo", "Bar");

// NO MESSAGES FOR YOU!

Console.WriteLine("And press Enter to Exit, because computers...");
Console.ReadLine();

}
}
```

๊ฐ€์žฅ ์œ ์šฉํ•œ ๋Œ“๊ธ€

e55b89a45618d222e2c37a3b14969923c998899b์—์„œ ์ˆ˜์ •๋จ

๋ชจ๋“  4 ๋Œ“๊ธ€

๋‚ด๊ฐ€ ์ด๊ฒƒ์„ ๊ฑฑ์ •ํ•˜๋Š” ์ด์œ ๋Š” ๋‹จ์ง€ ์ŠคํŒŒ์ดํฌ์— ๋ถˆ๊ณผํ•˜์ง€๋งŒ ๋‚ด๊ฐ€ ์ž‘์—…ํ•˜๊ณ  ์žˆ๋Š” ์‹ค์ œ ์„œ๋น„์Šค๋Š” WPF ๋ฐ์Šคํฌํ†ฑ ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ASP.NET Web API ์„œ๋น„์Šค์—์„œ๋„ ์‚ฌ์šฉ๋˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ ๋งค์šฐ ์•”๋ฌต์ ์ธ ๊ต์ฐฉ ์ƒํƒœ์ž…๋‹ˆ๋‹ค. ์ถ”์ ์„ ์ผœ๋ฉด ์ด์ „ ์ฝœ๋ฐฑ์ด ์•„์ง ์™„๋ฃŒ๋˜์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์— ์ฝœ๋ฐฑ๋งŒ ํ˜ธ์ถœ๋˜์ง€ ์•Š๊ณ  ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๋ฉ”์‹œ์ง€๋ฅผ ๊ณ„์† ์ˆ˜์‹ ํ•˜๊ณ  ์žˆ์Œ์„ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

And press Enter to Exit, because computers...
16:44:27.6966075 - b8022975-3d42-4935-952d-7c43a392d049 - WS: OnMessage({"C":"d-59F20992-B,18|S,0|T,1","M":[{"H":"ChatHub","M":"broadcastMessage","A":["adfasf","sadf"]}]})
16:44:28.6936798 - b8022975-3d42-4935-952d-7c43a392d049 - WS: OnMessage({})
16:44:31.4080330 - b8022975-3d42-4935-952d-7c43a392d049 - WS: OnMessage({"C":"d-59F20992-B,19|S,0|T,1","M":[{"H":"ChatHub","M":"broadcastMessage","A":["adfasf","adfsa"]}]})
16:44:36.2056851 - b8022975-3d42-4935-952d-7c43a392d049 - OnError(Microsoft.AspNet.SignalR.Client.Infrastructure.SlowCallbackException: Possible deadlock detected. A callback registered with "HubProxy.On" or "Connection.Received" has been executing for at least 10 seconds.)
16:44:38.6935113 - b8022975-3d42-4935-952d-7c43a392d049 - WS: OnMessage({})

Console.ReadLine(); ๋ฅผ await Console.In.ReadLineAsync() ๋กœ ๋ณ€๊ฒฝํ•˜์—ฌ ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ๊ธฐ๋ณธ์ ์œผ๋กœ ์‚ฌ์šฉ์ž ์ฝ”๋“œ๊ฐ€ TaskCompletionSource.SetResult(๋กœ ์™„๋ฃŒ๋œ ์ž‘์—…๊ณผ ๋™์ผํ•œ ์Šค๋ ˆ๋“œ์—์„œ ์‹คํ–‰๋˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ). ํด๋ผ์ด์–ธํŠธ๋Š” TCS๋ฅผ ์ƒ์„ฑํ•  ๋•Œ ์„ค์ • ๊ฒฐ๊ณผ๋ฅผ ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๋กœ ๋ณด๋‚ด๊ฑฐ๋‚˜ TaskCreationOption.RunContinuationsAsynchronously ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ด ์Šค๋ ˆ๋“œ๋Š” ๊ฐ„๋‹จํžˆ ๋งํ•ด์„œ ๋‚ด ๋น„๋™๊ธฐ ๋Œ€๊ธฐ ๊ฒฝํ—˜์ž…๋‹ˆ๋‹ค.

e55b89a45618d222e2c37a3b14969923c998899b์—์„œ ์ˆ˜์ •๋จ

์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰