1

await / async を使用することが、レスポンシブ UI を確保するための最良のアイデアであると考えました。しかし、とにかくアプリケーションがフリーズするため、何か間違っているようです。

私がやろうとしていること:ボタンが起動され、長時間の操作を待つ必要があります。

public async Task CmdLoadExcel()
{
    // läd die excel datei
   string[] excelFiles = this.GetExcelFiles();
   ExcelLoader eloader = new ExcelLoader();
   await eloader.StartLoading(excelFiles);
   foreach (DataSet elem in eloader.Tables)
   {
       this.ActivateItem(new ExcelViewModel(elem) { DisplayName = elem.DataSetName });
   }
}

起動されたクラス:

public async Task StartLoading(string[] files)
        {
            foreach (string file in files)
            {
                Stopwatch swatch = new Stopwatch();
                swatch.Start();
                System.Threading.Thread.Sleep(5000);
                FileInfo finfo = new FileInfo(file);
                using (ExcelPackage package = new ExcelPackage(finfo))
                {
                // very long operation
                }
            } // For Each
        } // StartLoading

それは単に睡眠中に停止し、何が間違っていたのかわかりません。

4

4 に答える 4

3

メソッドを async と await でマークしても、それ自体では実際には何もしません。タスクを待つ必要があります:

これは役立ちます:

public async Task StartLoading(string[] files)
{
    return Task.Run(() =>
    {            
        foreach (string file in files)
        {
            Stopwatch swatch = new Stopwatch();
            swatch.Start();
            System.Threading.Thread.Sleep(5000);
            FileInfo finfo = new FileInfo(file);
            using (ExcelPackage package = new ExcelPackage(finfo))
            {
            // very long operation
            }
        } // For Each
    };
} // StartLoading
于 2013-04-15T13:05:12.657 に答える
2

あなたStartLoadingの方法には、awaitステートメントが欠けているようです。キーワードは、魔法のasyncようにメソッドを非同期で実行できるようにするわけではありません。のasync-alterativeawaitとして. 非常に長い操作の場合、CPU バウンドの場合は、おそらく新しいスレッドを生成する必要があります。IO バウンドの場合、使用できる非同期 API にアクセスできるかどうかが問題になります。Task.DelayThread.Sleep

適切な紹介の開始については、MSDN Channel 9 のAsysnc に関する 3 つの重要なヒントを参照してください。

于 2013-04-15T13:09:58.537 に答える
1

問題は、StartLoading タスク自体が非同期ではないことです。次のコードを使用してこれを修正できます。

public Task StartLoading(string[] files)
{
    return Task.Factory.StartNew(() =>
        {
            foreach (string file in files)
            {
                Stopwatch swatch = new Stopwatch();
                swatch.Start();
                System.Threading.Thread.Sleep(5000);
                FileInfo finfo = new FileInfo(file);
                using (ExcelPackage package = new ExcelPackage(finfo))
                {
                        // very long operation
                }
            } // For Each    
        });
} // StartLoading

次に、次のようにコードを使用できます。

public Task CmdLoadExcel()
{
    // läd die excel datei
   string[] excelFiles = this.GetExcelFiles();
   ExcelLoader eloader = new ExcelLoader();

   var task = eloader.StartLoading(excelFiles);
   return task.ContinueWith(t =>
            {
                foreach (DataSet elem in eloader.Tables)
                {
                    this.ActivateItem(new ExcelViewModel(elem) { DisplayName = elem.DataSetName });
                }
            });
 }
于 2013-04-15T13:05:25.953 に答える
1

問題は、「await eloader.StartLoading(excelFiles);」という行である可能性があると思われます。実際には同じ(UI)スレッドで実行されています。以下のように実行する必要があります。これにより、メソッドが ThreadPool スレッドで実行されます。

await Task.Run(eloader.StartLoading(excelFiles));
于 2013-04-15T13:16:51.103 に答える