Поток не действует асинхронно - PullRequest
0 голосов
/ 01 февраля 2012

У меня есть приложение WPF, написанное на C #. Это делает вызов службе WCF, которую я написал. Время от времени для возврата службе WCF может потребоваться до 20 секунд (в зависимости от того, требуется ли обновить данные). Я знаю, что могу сделать так, чтобы служба WCF поддерживала асинхронные вызовы, но я подумал, что еще одно решение будет заключаться в том, чтобы заключить вызов службы WCF в новый поток. Я сделал это с помощью следующего кода:

new System.Threading.Thread(
    new System.Threading.ThreadStart(
    delegate()
    {
        Action del = delegate()
        {
            MyService.MyServiceClient ms = new MyService.MyServiceClient();
            lblTotalCost.Text = ms.GetTotalCost().ToString("C");
        };

        this.Dispatcher.BeginInvoke(del);
    })).Start();

Я поместил это в функцию конструктора одного из моих UserControls, после InitializeComponent ().

Без этого приложение не будет отображаться до тех пор, пока сервисный вызов не завершится. Я надеялся, что добавление этого сделает так, чтобы приложение появилось немедленно и чтобы метка заполнялась после завершения вызова службы. К моему удивлению, этого не произошло. Приложение по-прежнему не отображается, пока не завершится вызов службы.

Как это нужно изменить, чтобы оно выполняло то, что я намеревался сделать?

Спасибо!

Ответы [ 2 ]

3 голосов
/ 01 февраля 2012

Используя Dispatcher, вы помещаете все работу обратно в поток пользовательского интерфейса.Полагаю, там должно быть сделано только присвоение lblTotalCost.Text.

MyService.MyServiceClient ms = new MyService.MyServiceClient();
var value = ms.GetTotalCost().ToString("C");

this.Dispatcher.BeginInvoke(new Action(() => lblTotalCost.Text = value));
2 голосов
/ 01 февраля 2012

Вы создаете другой поток, который немедленно вызывает ваш поток пользовательского интерфейса для выполнения фактической работы (с помощью этого вызова Dispatcher.BeginInvoke).

То, что вы хотите, чтобы фоновый поток выполнял длительный циклработа, затем перезвоните в пользовательский интерфейс:

new System.Threading.Thread(
new System.Threading.ThreadStart(
delegate()
{
    MyService.MyServiceClient ms = new MyService.MyServiceClient();
    var v = ms.GetTotalCost();
    Action del = delegate()
    {
        lblTotalCost.Text = v.ToString("C");
    };

    this.Dispatcher.BeginInvoke(del);
})).Start();
...