【问题标题】:Dispatcher.Invoke() on Windows Phone 7?Windows Phone 7 上的 Dispatcher.Invoke()?
【发布时间】:2012-11-30 21:05:56
【问题描述】:

在回调方法中,我试图像这样获取文本框的文本属性:

string postData = tbSendBox.Text;

但是因为它没有在 UI 线程上执行,所以它给了我一个跨线程异常。

我想要这样的东西:

Dispatcher.BeginInvoke(() =>
{
    string postData = tbSendBox.Text;
});

但这是异步运行的。同步版本为:

Dispatcher.Invoke(() =>
{
    string postData = tbSendBox.Text;
});

但 Windows Phone 不存在 Dispatcher.Invoke()。有没有等价的东西?有不同的方法吗?

这是整个函数:

public void GetRequestStreamCallback(IAsyncResult asynchronousResult)
    {
        HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;

        // End the operation
        Stream postStream = request.EndGetRequestStream(asynchronousResult);

        string postData = tbSendBox.Text;

        // Convert the string into a byte array.
        byte[] byteArray = Encoding.UTF8.GetBytes(postData);

        // Write to the request stream.
        postStream.Write(byteArray, 0, postData.Length);
        postStream.Close();

        // Start the asynchronous operation to get the response
        request.BeginGetResponse(new AsyncCallback(GetResponseCallback), request);
    }

【问题讨论】:

    标签: windows-phone-7 dispatcher


    【解决方案1】:

    不,你是对的,你只能访问异步的。为什么要同步,因为您在 UI 的不同线程上?

    Deployment.Current.Dispatcher.BeginInvoke(() =>
           {
                string postData = tbSendBox.Text;
            });
    

    【讨论】:

    • 因为我需要将 postData 变量设置为 textBox 的文本,然后再继续执行其余的函数。我想我的总体问题是:我如何从不是 UI 线程的线程GET UI 属性。
    • 或者,如何调用带参数的回调函数,即:myReq.BeginGetRequestStream(new AsyncCallback(GetRequestStreamCallback **ARGUMENTS??**), myReq);
    • 我认为它违背了 Windows Phone 异步模型的目的:UI 优先于所有其他背景任务,以防止用户体验不佳(渲染缓慢等)。也许您可以通过显示“正在加载”或“正在更新”之类的消息来缓解......
    【解决方案2】:

    这应该对同步进行异步调用:

      Exception exception = null;
      var waitEvent = new System.Threading.ManualResetEvent(false);
      string postData = "";
      Deployment.Current.Dispatcher.BeginInvoke(() =>
      {
        try
        {
          postData = tbSendBox.Text;
        }
        catch (Exception ex)
        {
          exception = ex;
        }
        waitEvent.Set();
      });
      waitEvent.WaitOne();
      if (exception != null)
        throw exception;
    

    【讨论】:

    • 我试过这个。这似乎是有道理的,但线程在分派到另一个线程之前在 WaitOne() 上被阻塞,所以它永远不会到达 Set()
    • @Lemontongs,你错了。如果您在非 ui 线程中执行此代码,它会按您的需要工作.. ps。我在我的程序中使用此代码进行同步操作。
    【解决方案3】:

    1) 获取UI线程同步上下文的引用。例如,

    SynchronizationContext context = SynchronizationContext.Current
    

    2) 然后将您的回调发布到此上下文。这就是 Dispatcher 内部的工作方式

    context.Post((userSuppliedState) => { }, null);
    

    这是你想要的吗?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-04-10
      • 2012-09-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多