LoginSignup
34
41

More than 5 years have passed since last update.

C#で、asyncを利用した別タスクから、UIコントロールをさわる

Last updated at Posted at 2015-12-31

C#で、重い処理をしているときなどに、マルチスレッドで、
別タスクからUIをさわりたいときがあるのですが、エラーが出てしまいます。

そんなときは、Task型の関数を、awaitで実行すればいいのです。

taskUI.cs
using System.Threading.Tasks;

// 省略

async void Main()
{
    var heavyResult = await runTask(); // 1.
    label1.Text = heavyResult;
}
async Task<string> runTask()
{
    await Task.Delay(1000); // 2.
    return "hogehoge"; // 3.
}

番号はコード内のコメントの番号と対応しています。
1. 非同期でrunTask関数を実行
2. 別Taskでの動作の確認のために、1秒間止める。この間もUIは動作する。
3. 1秒間たった後、文字列hogehogeを返す。
4. 戻り値をlabelに書きだす。

  • Mainメソッドに、asyncをつけています

また、タスクを別のメソッドにしなくてもできるようです。

taskUI2.cs
using System.Threading.Tasks;

// 省略

async void Main()
{
    var heavyResult = await Task.Run(async () =>
    {
        await Task.Delay(1000);
        return "fugafuga";
    }
    label1.Text = heavyResult;
}

何回もLabelを書き替えたい

なんか重い処理が、「何%進みました」みたいな処理をやるときは、
複数回Labelを書き替える必要があります。
その時は、Taskをつなげて行うのではなく、1%ごとに分けて行うとできます。

async void Main()
{
    for (var i = 0; i < 100; i++)
    {
        label1.Text = await progress(i);
    }
}
async Task<string> progress(int percent)
{
    await Task.Delay(100);
    return $"{percent}% 完了しました";
}

追記:Reactive Extensions

Reactive Extensionsを使うと、複数のタスクに分けず、JavaScriptのコールバックみたいなことができます。
デフォルトでは、Reactive Extensionsが入っていないので、
NuGetで「Rx-main」をインストールしてください。
詳細: https://msdn.microsoft.com/en-us/data/gg577610.aspx#dotnet

using System.Reactive.Linq;
using System.Reactive.Disposables;
using System.Threading.Tasks;

void Main()
{
    Observable.Create<string>(async o =>
    {
        for (var i = 0; i < 100; i++)
        {
            await Task.Delay(100);
            o.OnNext($"{i}% 完了しました。");
        }
        o.OnNext("最後の処理をしています...");
        await Task.Delay(1000);
        o.OnNext("完了");
        return Disposable.Empty;
    }).Subscribe(x =>
    {
        label1.Text = x;
    });
}

この方法だと、毎回違う処理をする場合でも、一つのObservableで処理ができます。

NetSeedさん、chocolamintさん、ありがとうございます。

34
41
10

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
34
41