콘솔 애플리케이션에 활동 표시기 표시
19610 단어 ReactiveExtensions우이RxF#C#
개요
콘솔 응용 프로그램에서 무거운 처리를 실행 중임을 사용자에게 알리기 위해 활동 표시기를 표시하는 프로그램을 C#과 F#으로 작성했습니다.
일정 시간마다 ...
를 표시하기 위해 Rx ( Observable.Timer
)를 사용했습니다.
処理中
処理中.
処理中..
処理中...
処理完了
C# 버전
nuget으로 System.Reactive
를 설치하십시오.
using System;
using System.Reactive.Linq;
using System.Threading;
using System.Threading.Tasks;
class Program {
// アクティビティインジケータを出力する関数
static void IndicationPrinter(string msg1, string msg2, int i) {
Console.SetCursorPosition(0, Console.CursorTop);
if (i < 0) {
Console.WriteLine(msg2);
} else {
var n = i % 4;
Console.Write($"{msg1}{new string('.', n)}{new string(' ', 3 - n)}");
}
}
// インジケータを出力しながら関数funcをする非同期で実行する関数
static Task<T> RunWithActivityIndicator<S, T>(string msg1, string msg2, Func<S, T> func, S arg) {
var sTimer = Observable.Timer(TimeSpan.FromSeconds(0), TimeSpan.FromSeconds(0.2));
var timerSubscription = sTimer.Subscribe(i =>
IndicationPrinter(msg1, msg2, (int)i));
return Task.Run(() => {
return func(arg);
}).ContinueWith((Task<T> t) => {
timerSubscription.Dispose();
IndicationPrinter(msg1, msg2, -1);
return t.Result;
});
}
static void Main(string[] args) {
Console.WriteLine("C# Ver.");
//Console.CursorVisible = false; //カーソルを消したい場合
Func<string, string> heavyWeightFunc1 = (string arg) => {
Thread.Sleep(2500);
return $"=={arg}==";
};
// 非常に時間がかかる関数1 (Func<int>)
Func<int> heavyWeightFunc2 = () => {
Thread.Sleep(1500);
return 0;
};
var msg1 = "処理中";
var msg2 = "処理完了";
var task1 = RunWithActivityIndicator(msg1, msg2, heavyWeightFunc1, "hoge");
Console.WriteLine($"処理結果:{task1.Result}");
Console.ReadKey();
}
}
F#판
nuget으로 FSharp.Control.Reactive
를 설치하십시오.
open System
open System.Reactive.Linq
open FSharp.Control.Reactive
open System.Threading
open System.Threading.Tasks
// アクティビティインジケータを出力する関数
let indicationPrinter msg1 msg2 i =
Console.SetCursorPosition(0, Console.CursorTop) |> ignore
if i < 0 then
printfn "%s" msg2
else
match i%4 with
| 0 -> ignore( printf "%s" (msg1+" "))
| 1 -> ignore( printf "%s" (msg1+". "))
| 2 -> ignore( printf "%s" (msg1+".. "))
| _ -> ignore( printf "%s" (msg1+"..."))
// インジケータを出力しながら関数funcをする非同期で実行する関数
let runWithActivityIndicator (msg1,msg2) (func:'S->'T) arg =
let indicationPrinter = indicationPrinter msg1 msg2
let sTimer = Observable.Timer(TimeSpan.FromSeconds(0.),TimeSpan.FromSeconds(0.2))
let timerSubscription = sTimer.Subscribe( fun i -> int(i) |> indicationPrinter )
let task = async { return func arg } |> Async.StartAsTask
task.ContinueWith( fun (t:Task<'T>) ->
timerSubscription.Dispose()
indicationPrinter -1
t.Result )
[<EntryPoint>]
let main argv =
printfn "F# Ver."
//Console.CursorVisible <- false; // カーソルを消したい場合
// 非常に時間がかかる関数1 (string->string)
let heavyWeightFunc1 arg =
Thread.Sleep(1500)
"==" + arg + "=="
// 非常に時間がかかる関数2 (unit->string)
let heavyWeightFunc2 () =
Thread.Sleep(2500)
0
// 非常に時間がかかる関数3 (unit->unit)
let heavyWeightFunc3 () =
Thread.Sleep(1000)
let msg = ("処理中","処理完了")
let task1 = runWithActivityIndicator msg heavyWeightFunc1 "hoge"
printfn "%s" ("処理結果 : " + task1.Result )
let task2 = runWithActivityIndicator msg heavyWeightFunc2 ()
printfn "%s" ("処理結果 : " + (task2.Result.ToString()) )
let task3 = runWithActivityIndicator msg heavyWeightFunc3 ()
task3.Wait()
printfn "."
Console.ReadKey() |> ignore
0
참고 자료
using System;
using System.Reactive.Linq;
using System.Threading;
using System.Threading.Tasks;
class Program {
// アクティビティインジケータを出力する関数
static void IndicationPrinter(string msg1, string msg2, int i) {
Console.SetCursorPosition(0, Console.CursorTop);
if (i < 0) {
Console.WriteLine(msg2);
} else {
var n = i % 4;
Console.Write($"{msg1}{new string('.', n)}{new string(' ', 3 - n)}");
}
}
// インジケータを出力しながら関数funcをする非同期で実行する関数
static Task<T> RunWithActivityIndicator<S, T>(string msg1, string msg2, Func<S, T> func, S arg) {
var sTimer = Observable.Timer(TimeSpan.FromSeconds(0), TimeSpan.FromSeconds(0.2));
var timerSubscription = sTimer.Subscribe(i =>
IndicationPrinter(msg1, msg2, (int)i));
return Task.Run(() => {
return func(arg);
}).ContinueWith((Task<T> t) => {
timerSubscription.Dispose();
IndicationPrinter(msg1, msg2, -1);
return t.Result;
});
}
static void Main(string[] args) {
Console.WriteLine("C# Ver.");
//Console.CursorVisible = false; //カーソルを消したい場合
Func<string, string> heavyWeightFunc1 = (string arg) => {
Thread.Sleep(2500);
return $"=={arg}==";
};
// 非常に時間がかかる関数1 (Func<int>)
Func<int> heavyWeightFunc2 = () => {
Thread.Sleep(1500);
return 0;
};
var msg1 = "処理中";
var msg2 = "処理完了";
var task1 = RunWithActivityIndicator(msg1, msg2, heavyWeightFunc1, "hoge");
Console.WriteLine($"処理結果:{task1.Result}");
Console.ReadKey();
}
}
nuget으로
FSharp.Control.Reactive
를 설치하십시오.open System
open System.Reactive.Linq
open FSharp.Control.Reactive
open System.Threading
open System.Threading.Tasks
// アクティビティインジケータを出力する関数
let indicationPrinter msg1 msg2 i =
Console.SetCursorPosition(0, Console.CursorTop) |> ignore
if i < 0 then
printfn "%s" msg2
else
match i%4 with
| 0 -> ignore( printf "%s" (msg1+" "))
| 1 -> ignore( printf "%s" (msg1+". "))
| 2 -> ignore( printf "%s" (msg1+".. "))
| _ -> ignore( printf "%s" (msg1+"..."))
// インジケータを出力しながら関数funcをする非同期で実行する関数
let runWithActivityIndicator (msg1,msg2) (func:'S->'T) arg =
let indicationPrinter = indicationPrinter msg1 msg2
let sTimer = Observable.Timer(TimeSpan.FromSeconds(0.),TimeSpan.FromSeconds(0.2))
let timerSubscription = sTimer.Subscribe( fun i -> int(i) |> indicationPrinter )
let task = async { return func arg } |> Async.StartAsTask
task.ContinueWith( fun (t:Task<'T>) ->
timerSubscription.Dispose()
indicationPrinter -1
t.Result )
[<EntryPoint>]
let main argv =
printfn "F# Ver."
//Console.CursorVisible <- false; // カーソルを消したい場合
// 非常に時間がかかる関数1 (string->string)
let heavyWeightFunc1 arg =
Thread.Sleep(1500)
"==" + arg + "=="
// 非常に時間がかかる関数2 (unit->string)
let heavyWeightFunc2 () =
Thread.Sleep(2500)
0
// 非常に時間がかかる関数3 (unit->unit)
let heavyWeightFunc3 () =
Thread.Sleep(1000)
let msg = ("処理中","処理完了")
let task1 = runWithActivityIndicator msg heavyWeightFunc1 "hoge"
printfn "%s" ("処理結果 : " + task1.Result )
let task2 = runWithActivityIndicator msg heavyWeightFunc2 ()
printfn "%s" ("処理結果 : " + (task2.Result.ToString()) )
let task3 = runWithActivityIndicator msg heavyWeightFunc3 ()
task3.Wait()
printfn "."
Console.ReadKey() |> ignore
0
참고 자료
Reference
이 문제에 관하여(콘솔 애플리케이션에 활동 표시기 표시), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/code0327/items/1fdc0464dc3674b537a6텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)