2017-04-24 20 views
3

UIスレッドでデータを更新中に3〜10秒間UIがフリーズするUIスレッドのデータをフリーズせずに更新したい。c#WPF UIがハングするUIスレッドのデータを更新する

コード:Getdata()

インサイド

Task t = Task.Factory.StartNew(() => 
{ 
    // Get data from Server 
    GetData(true); 
}); 

//Converst JSON to DataSet Object:- "tempDataSet" 
Task task = Task.Factory.StartNew(() => 
{    
    RetriveData(tempDataSet, firstTime); 
}, CancellationToken.None, TaskCreationOptions.None, MainFrame.Current); 

RetriveData

DataTable response = tempDataSet.Tables["response"]; 
DataTable conversations = tempDataSet.Tables["convo"]; 

foreach (DataRow row in conversations.Rows) // UI Hangs in the method 
{ 
    UC_InboxControl control = new UC_InboxControl(row, uC_Inbox); 
    if (uC_Inbox.mnuUnreadChat.IsChecked == false) 
    { 
      inboxControlCollection.Add(control); 
    } 
    else 
    { 
      inboxUnreadOnlyControlCollection.Add(control); 
    } 
} 

インサイドハングせずにUIスレッドでUIを更新または凍結するための最良の方法は何ですか?

+0

Getdata()内で新しいタスクを開始するのはなぜですか?完全なコードを投稿してください。 – mm8

+0

RetriveData内にUI操作があります。私はUI更新のために新しいタスクを使用しました。 –

+0

GetDataにUI操作はどこにありますか?これは意味がありません。すべてのUI操作はUIスレッドをフリーズします。 – mm8

答えて

3

GetDataメソッドは、どのUI要素にもアクセスしないでください。これはバックグラウンドスレッド上で実行され、ビューに表示するオブジェクトのリストを返します。あなたが戻っUIスレッド上で、これらのオブジェクトとObservableCollectionを移入するContinueWithメソッドを使用することができ、例えば:同じ結果がasync/awaitを達成することができる

Task t = Task.Factory.StartNew(() => 
{ 
    return GetData(true); // <-- GetData should return a collection of objects 
}).ContinueWith(task => 
{ 
    //that you add to your ObservableCollection here: 
    foreach (var item in task.Result) 
     yourObservableCollection.Add(item); 
}, 
System.Threading.CancellationToken.None, TaskContinuationOptions.None, TaskScheduler.FromCurrentSynchronizationContext()); 
+1

毎回私を助けてくれてありがとう... –

+0

あなたは歓迎です:) – mm8

0

、タスクの完了後にUIのコンテキストを復元します:

// await the task itself, after that do the UI stuff 
var collection = await Task.Run(() => 
{ 
    // directly call the retrieve data 
    return RetriveData(tempDataSet, firstTime); 
}); 

// this code will resume on UI context 
foreach (var item in collection) 
{ 
    var control = new UC_InboxControl(row, uC_Inbox); 
    if (!uC_Inbox.mnuUnreadChat.IsChecked) 
    { 
     inboxControlCollection.Add(control); 
    } 
    else 
    { 
     inboxUnreadOnlyControlCollection.Add(control); 
    } 
} 

ご覧のとおり、私はRetriveDataをここに直接呼び出します。

public async Task<> GetData(...) 
{ 
    // some code ... 
    return await Task.Run(() => 
    { 
     return RetriveData(tempDataSet, firstTime)); 
    } 
} 

をあなたはasyncとしてメソッドをマークする必要があり、これを達成するために:あなたが行うことができますので、また、あなたは、あまりにもasyncとしてそれをマークすることができます。イベントハンドラの場合はasync void、それ以外の場合はasync Taskを使用できます。

+0

はお試しいただきありがとうございます –

関連する問題