teratail header banner
teratail header banner
質問するログイン新規登録

質問編集履歴

5

修正

2019/06/08 02:27

投稿

firstlast
firstlast

スコア138

title CHANGED
File without changes
body CHANGED
@@ -117,7 +117,7 @@
117
117
 
118
118
  ```
119
119
 
120
- 修正
120
+ 問題解決のソースコード
121
121
  ```
122
122
  using System;
123
123
  using System.Collections.Generic;

4

修正後のソースを追加

2019/06/08 02:27

投稿

firstlast
firstlast

スコア138

title CHANGED
File without changes
body CHANGED
@@ -116,6 +116,110 @@
116
116
  }
117
117
 
118
118
  ```
119
+
120
+ 修正後
121
+ ```
122
+ using System;
123
+ using System.Collections.Generic;
124
+ using System.ComponentModel;
125
+ using System.Data;
126
+ using System.Drawing;
127
+ using System.Linq;
128
+ using System.Text;
129
+ using System.Threading.Tasks;
130
+ using System.Windows.Forms;
131
+
132
+ using System.Net;
133
+ using System.IO;
134
+ using System.Text.RegularExpressions;
135
+
136
+ namespace Asynctest
137
+ {
138
+ public partial class Form1 : Form
139
+ {
140
+ public Form1()
141
+ {
142
+ InitializeComponent();
143
+ }
144
+
145
+ private async void Button1_Click(object sender, EventArgs e)
146
+ {
147
+ const string url = @"http://192.168.0.99/";
148
+
149
+ // スレッドを起動し、以降のコードを実行する前に呼び出し元へ戻る
150
+ await Task.Run(() =>
151
+ {
152
+ //非同期で実行したい重い処理
153
+ //Task.Delay(1000).Wait();
154
+ byte[] data;
155
+ WebRequest req = null;
156
+ WebResponse res = null;
157
+ string str = null;
158
+
159
+ try
160
+ {
161
+ req = WebRequest.Create(url);
162
+ res = req.GetResponse();
163
+ Stream st = res.GetResponseStream();
164
+ data = ReadBinaryData(st);
165
+ str = System.Text.Encoding.GetEncoding("csISO2022JP").GetString(data);
166
+ }
167
+ catch (Exception ex)
168
+ {
169
+ Console.WriteLine(ex.Message);
170
+
171
+ //UI要素へのアクセス(非同期で実行したい処理と混ぜずに、単独で行う。)
172
+ this.Invoke(new Action(() => {
173
+ listBox1.Items.Insert(listBox1.Items.Count, ex.Message);
174
+ }));
175
+ return;
176
+ }
177
+ finally
178
+ {
179
+ if (res != null) res.Close();
180
+ }
181
+ //UI要素へのアクセス(非同期で実行したい処理と混ぜずに、単独で行う。)
182
+ this.Invoke(new Action(() => {
183
+ listBox1.Items.Insert(listBox1.Items.Count, str);
184
+ }));
185
+
186
+ });
187
+
188
+ }
189
+
190
+ static byte[] ReadBinaryData(Stream st)
191
+ {
192
+ byte[] buf = new byte[32768];
193
+ using (MemoryStream ms = new MemoryStream())
194
+ {
195
+ while (true)
196
+ {
197
+ int r = st.Read(buf, 0, buf.Length);
198
+
199
+ //一時バッファの内容をメモリ・ストリームに書き込む
200
+ if (r > 0)
201
+ {
202
+ ms.Write(buf, 0, r);
203
+ }
204
+ else
205
+ {
206
+ break;
207
+ }
208
+ }
209
+ return ms.ToArray();
210
+ }
211
+ }
212
+
213
+ private void Button2_Click(object sender, EventArgs e)
214
+ {
215
+ listBox1.Items.Insert(listBox1.Items.Count, "!");
216
+
217
+ }
218
+ }
219
+ }
220
+ ```
221
+
222
+
119
223
  ### 環境
120
224
  Microsoft Windows 10 Pro (Version 1809)
121
225
  Microsoft Visual Studio Community 2017(Version 15.9.4)

3

修正

2019/06/08 01:54

投稿

firstlast
firstlast

スコア138

title CHANGED
@@ -1,1 +1,1 @@
1
- WEBページ読み込み中に、UI操作を行いたいのですが、処理がブロックされ上手く行きません。
1
+ 重い処理処理中に、UI操作を行いたいのですが、処理がブロックされ上手く行きません。
body CHANGED
File without changes

2

修正

2019/06/07 09:54

投稿

firstlast
firstlast

スコア138

title CHANGED
File without changes
body CHANGED
@@ -1,5 +1,5 @@
1
1
  ### 前提・実現したいこと
2
- WEBページ読み込み中に、UI操作を行いたいのですが、処理がブロックされ上手く行きません。
2
+ 重い処理処理中に、UI操作を行いたいのですが、処理がブロックされ上手く行きません。
3
3
 
4
4
  ブロックされないようにするために、ソースコードには
5
5
   ・イベントプロシージャにasync を付ける。

1

補足

2019/06/07 09:53

投稿

firstlast
firstlast

スコア138

title CHANGED
File without changes
body CHANGED
@@ -11,6 +11,9 @@
11
11
  よろしくお願いします。
12
12
 
13
13
  下に画面イメージとソースコードを載せておきます。
14
+ 左のボタンがWEBページにアクセスするボタン
15
+ 右のボタンがUI操作を確認するためのボタンです。
16
+
14
17
  ソースコードは、Windows Formsアプリ、及びC#です。
15
18
  ![イメージ説明](d4f72dbacc923d96f6d7ef85328afb3b.jpeg)
16
19
 
@@ -41,11 +44,12 @@
41
44
 
42
45
  private async void Button1_Click(object sender, EventArgs e)
43
46
  {
44
- const string url = @"http://192.168.0.99/";
47
+ const string url = @"http://192.168.0.99/"; //レスポンスを遅くするために、意図的にこのURLにアクセス
45
48
 
46
49
  //スレッド起動
47
50
  await Task.Run(() =>
48
51
  {
52
+ //UIスレッドにアクセスするためにInvokeを使用
49
53
  this.Invoke(new Action(() =>
50
54
  {
51
55
  //Task.Delay(1000).Wait();
@@ -102,6 +106,7 @@
102
106
  }
103
107
  }
104
108
 
109
+ //リストボックスに1行追加するだけ
105
110
  private void Button2_Click(object sender, EventArgs e)
106
111
  {
107
112
  listBox1.Items.Insert(listBox1.Items.Count - 1, "!");