質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Xamarin

Xamarin(ザマリン)は、iPhoneなどのiOSやAndroidで動作し、C# 言語を用いてアプリを開発できるクロスプラットフォーム開発環境です。Xamarin Studioと C# 言語を用いて、 iOS と Android の両方の開発を行うことができます。

Q&A

解決済

1回答

6423閲覧

xamarinFormsにて、コントロールの画面更新を自由にしたい

kamingout

総合スコア44

Xamarin

Xamarin(ザマリン)は、iPhoneなどのiOSやAndroidで動作し、C# 言語を用いてアプリを開発できるクロスプラットフォーム開発環境です。Xamarin Studioと C# 言語を用いて、 iOS と Android の両方の開発を行うことができます。

0グッド

0クリップ

投稿2017/05/23 14:38

現在、XamarinFormsでアプリを実装中です。
Buttonコントロールクリック時に入るOnClickedButton関数の中でデータバインディングにより、
ループでBeginInvokeOnMainThreadを呼び出すことでLabelコントロールのテキストを
逐一変更するような処理を想定して実装しているのですが、OnClickedButtonから抜けた後でしかコントロールに反映されません。

private void Button_Clicked(object sender, EventArgs e) { int i = 0; while (i < 100000) { Device.BeginInvokeOnMainThread(() => { this.CCounter.Counter = i.ToString(); this.Label1.Text = this.CCounter.Counter; }); i++; } }

何が原因と考えられますでしょうか?
また、良い解決策がございましたら教えていただきたいです。

よろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

今のXamarin.Formsの実装ではBeginInvokeOnMainThreadはiOS・AndroidともにUIスレッドに処理をポストするだけで、その処理は後で行われます。
この場合ですと10万回処理がポストされた後Button_Clickedの処理を抜け、そのあとUIのメッセージポンプよりポストされた処理を順次実行します。
BeginInvokeOnMainThreadを通さなければすぐに実行されますが、それが画面に反映されるかと言えばそれは実行プラットフォームによると思いますが、おそらく反映されないかと思います。またそのように実装するのはUIスレッドを止めてしまうことになるのでやるべきではないです。

やりたいことは時間のかかる処理を開始してその経過をカウンターで見たいというものでしょうか?
その場合はその時間のかかる処理をUIスレッド上で行うのかワーカースレッドで行うかにより実装方法が変わってきます。
UIスレッド上で行うのなら処理の繰り返し中に適度に抜けてUIメッセージポンプが処理されないといけません。適度に抜ける的な挙動をいい感じにやるのは色々方法がありますが、場合によってはやりたい処理以外のそれららのコードが入って見通しが悪くなるなどもあり得そう。
ワーカースレッドで行うなら処理中に上にあるように処理中にBeginInvokeOnMainThreadを通してカウンターを更新する処理を呼べばいいのでUIスレッドでやるよりは実装しやすいかもしれませんね。

どちらにしてもこのほかに処理の開始前後でボタンを有効無効にするなどもありますが、本筋から外れるので割愛。

投稿2017/05/24 03:12

omanuke

総合スコア109

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kamingout

2017/05/25 13:52

御回答ありがとうございます。 根本的に実装の仕方が違っていたということがわかりました。 ワーカースレッドを立てて、そこでUIプロパティの変更をし、BeginInvokeOnMainThreadにて更新するようなやり方にしてみようと思います。
omanuke

2017/05/25 14:03

ワーカースレッドでUIのプロパティをいじるとエラーになります。 その場合もBeginInvokeOnMainThreadなどでUIスレッド上で行われるようにする必要があるので注意ください。
kamingout

2017/05/27 15:36

ワーカースレッド上で以下のようにプロパティを書き換えようとしているのですが良くないコードなのでしょうか? Device.BeginInvokeOnMainThread(() => { CCounter.Counter = i.ToString(); Label1.Text = this.CCounter.Counter; }); 実際に、 var task = Task.Run(() => { DoWork(); }); このような形でDoWork関数を呼び出して処理させたところ、UIの更新がリアルタイムで反映されましたが、、、 お手数おかけしますが、ご返信よろしくお願いいたします。
kamingout

2017/05/27 15:37

上記の Device.BeginInvokeOnMainThread(() => { CCounter.Counter = i.ToString(); Label1.Text = this.CCounter.Counter; }); は、DoWork関数(ワーカースレッドで動作させている関数)の中の処理です。
omanuke

2017/05/27 15:45

Device.BeginInvokeOnMainThreadを挟んでるので問題ないと思います。
kamingout

2017/05/29 14:39

安心しました。 ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問