Причина Silverlight асинхронных API-интерфейсов зависает и не реагирует - PullRequest
3 голосов
/ 03 февраля 2010

этот код вызывает зависание Silverlight.Если я удалю код ManualResetEvent, ничего не произойдет

        private ManualResetEvent mre = new ManualResetEvent(false);

        ...

        WebClient sender = new WebClient();
        sender. += new OpenReadCompletedEventHandler(this.ReadComplete);
        sender.OpenReadAsync(new Uri(this.url+"?blob="+BODY, UriKind.Relative));

        mre.WaitOne();

    }
    public bool T = false;
    public void ReadComplete(object sender, OpenReadCompletedEventArgs e)
    {

        mre.Set();
    }

Ответы [ 2 ]

2 голосов
/ 03 февраля 2010

Вы не можете заблокировать в потоке пользовательского интерфейса (см. "Mre.WaitOne").Если вам абсолютно необходим WaitOne, вы должны запустить свой код в отдельном потоке.Это можно сделать следующим образом:

var t = new Thread(delegate()
{
    //...
    mre.WaitOne();
    //...
});

Можно ожидать, что в обратном вызове будет вызван «mre.Set ()»Однако у меня была та же проблема, поэтому очевидно, что механизм обратного вызова OpenReadAsync использует поток пользовательского интерфейса в качестве промежуточного диспетчера.Эта диспетчеризация не может произойти, она ожидает установки события.

0 голосов
/ 03 февраля 2010

Есть только несколько причин, по которым я могу видеть, что вы можете поверить, что вам нужно это ожидание блокировки.Либо вы не знаете, что вам следует продолжить работу с кодом в завершенном событии, либо у вас есть другое локальное состояние, которое вы не включили в пример кода, к которому у процедуры ReadCompleted нет доступа.* Вот некоторый код котельной пластины для обработки загруженного потока: -

string dummy = "Some value"; // local value you still need to access when download complete

WebClient wc = new WebClient();
wc.OpenReadCompleted += (s, args)
{
   if (!args.Cancelled)
   {
     try
     {
         Stream stream = args.Stream;  // This is the data you are after
         // Do stuff with stream, note the dummy variable is still accessible here.
     }
     catch (Exception err)
     {
         //Do something sensible with the exception to make sure its surfaced
     }
   }
};
sender.OpenReadAsync(new Uri(this.url+"?blob="+BODY, UriKind.Relative));
...