非常に単純な解決策を提案しますが、速度のパフォーマンスを考慮していない場合、元の質問に答えるのに最適ではありません。
...
public volatile bool IsSomethingLoading = false;
...
public async Task<SomeData> GetTheData()
{
// Launch the task asynchronously without waiting the end
_ = Task.Factory.StartNew(() =>
{
// Get the data from elsewhere ...
});
// Wait the flag
await Task.Factory.StartNew(() =>
{
while (IsSomethingLoading)
{
Thread.Sleep(100);
}
});
return TheData;
}
重要な注意: @Theodor Zoulias の提案:キーワードIsSomethingLoading
を使用して宣言する必要があります。これvolatile
により、コンパイラの最適化と、他のスレッドからアクセスする際の潜在的なマルチスレッドの問題を回避できます。コンパイラーの最適化の詳細については、次の記事に従ってください:
The C# Memory Model in Theory and Practice
以下に完全なテストコードを追加しています:
XAML :
<Label x:Name="label1" Content="Label" HorizontalAlignment="Left" Margin="111,93,0,0" VerticalAlignment="Top" Grid.ColumnSpan="2" Height="48" Width="312"/>
テストコード:
public partial class MainWindow : Window
{
// volatile keyword shall be used to avoid compiler optimizations
// and potential multithread issues when accessing IsSomethingLoading
// from other threads.
private volatile bool IsSomethingLoading = false;
public MainWindow()
{
InitializeComponent();
_ = TestASyncTask();
}
private async Task<bool> TestASyncTask()
{
IsSomethingLoading = true;
label1.Content = "Doing background task";
// Launch the task asynchronously without waiting the end
_ = Task.Factory.StartNew(() =>
{
Thread.Sleep(2000);
IsSomethingLoading = false;
Thread.Sleep(5000);
HostController.Host.Invoke(new Action(() => label1.Content = "Background task terminated"));
});
label1.Content = "Waiting IsSomethingLoading ...";
// Wait the flag
await Task.Run(async () => { while (IsSomethingLoading) { await Task.Delay(100); }});
label1.Content = "Wait Finished";
return true;
}
}
/// <summary>
/// Main UI thread host controller dispatcher
/// </summary>
public static class HostController
{
/// <summary>
/// Main Host
/// </summary>
private static Dispatcher _host;
public static Dispatcher Host
{
get
{
if (_host == null)
{
if (Application.Current != null)
_host = Application.Current.Dispatcher;
else
_host = Dispatcher.CurrentDispatcher;
}
return _host;
}
}
}