回答編集履歴

1

見直しキャンペーン中

2023/07/22 08:08

投稿

TN8001
TN8001

スコア9326

test CHANGED
@@ -1,129 +1,65 @@
1
1
  端的に言うと↓です。
2
-
3
- ```C#
2
+ ```cs
4
-
5
3
  BeginInvoke((Action<FileSystemEventArgs>)OnChangedInMainThread, e);
6
-
7
4
  ```
8
5
 
9
-
10
-
11
6
  ほかの点はコード中のコメントに入れました。
12
-
13
- ```C#
7
+ ```cs
14
-
15
8
  using System;
16
-
17
9
  using System.IO;
18
-
19
10
  using System.Windows;
20
-
21
11
  using System.Windows.Threading;
22
12
 
23
-
24
-
25
13
  namespace Questions273634
26
-
27
14
  {
28
-
29
15
  public partial class MainWindow : Window
30
-
31
16
  {
32
-
33
17
  private int count;
34
18
 
35
-
36
-
37
19
  public MainWindow()
38
-
39
20
  {
40
-
41
21
  InitializeComponent();
42
22
 
43
-
44
-
45
23
  var watcher = new FileSystemWatcher(Environment.CurrentDirectory);
46
-
47
24
  watcher.NotifyFilter = NotifyFilters.LastWrite;
48
-
49
25
  watcher.Changed += OnChanged;
50
-
51
26
  watcher.EnableRaisingEvents = true;
52
27
 
53
-
54
-
55
28
  // 検証がめんどくさいので自分でファイル変更
56
-
57
29
  var timer = new DispatcherTimer();
58
-
59
30
  timer.Interval = TimeSpan.FromSeconds(1);
60
-
61
31
  timer.Tick += (s, e) => File.WriteAllText(@"test.txt", "aaaa");
62
-
63
32
  timer.Start();
64
-
65
33
  }
66
34
 
67
-
68
-
69
35
  private void OnChanged(object sender, FileSystemEventArgs e)
70
-
71
36
  {
72
-
73
37
  // このメソッドがWindowのメソッドでないか、static限定なら
74
-
75
38
  // Application.Current.Dispatcher.BeginInvokeを使う
76
-
77
39
  // Windowのメソッドならthis.Dispatcher.BeginInvokeでいい
78
-
79
-
80
40
 
81
41
  // 指定しない限り別スレッドになるので、CheckAccessの確認は無駄な気がする
82
42
 
83
-
84
-
85
43
  Dispatcher.BeginInvoke((Action<FileSystemEventArgs>)OnChangedInMainThread, e);
86
-
87
44
  //Dispatcher.BeginInvoke((Action)(() => OnChangedInMainThread(e))); // ラムダで
88
-
89
45
  //Dispatcher.Invoke(() => OnChangedInMainThread(e)); // 同期 ラムダで
90
-
91
46
  }
92
47
 
93
-
94
-
95
48
  private void OnChangedInMainThread(FileSystemEventArgs e)
96
-
97
49
  {
98
-
99
50
  //new ImagePreview().Show();
100
51
 
101
-
102
-
103
52
  // xamlに<TextBlock x:Name="textBlock" />があるとして
104
-
105
53
  textBlock.Text = $"{e.Name} {DateTime.Now:yyyy/MM/dd HH:mm:ss.ffff} {count++}";
106
-
107
54
  }
108
-
109
55
  }
110
-
111
56
  }
112
-
113
57
  ```
114
-
115
-
116
58
 
117
59
  ---
118
60
 
119
-
120
-
121
61
  `FileSystemWatcher`は連続してイベント発火する場合がある(書き込んだアプリによるのでこちらで制御できない)ようなので、`Show()`だとちょっと困ったことになるかもしれません。
122
-
123
62
  厳密にやろうとすると、かなり面倒&これといって決定版がない気がします。
124
63
 
125
-
126
-
127
64
  簡易でいい場合は、↓なんかがスマートです。
128
-
129
65
  [FileSystemWatcherの連続して発生する同じ種類のイベントを無視る - かずきのBlog@hatena](https://blog.okazuki.jp/entry/20120322/1332378060)