2017-08-10 76 views
0

最终编辑:问题原来与此异步实现无关。第一个答案帮助我移动了足够的东西,用一双新的眼睛来看问题。多谢你们。等待时无响应的UI

我正在通过httpclient(请求并接收图像)和websocket(通过websocket-sharp,接收数据)在我的应用程序中使用IP摄像头进行通话。

现在我只是打开websocket,并要求一个图像(循环会稍后)。询问形象是我做的最后一件事。

当我定义该图像作为

string picloc = "[redacted]"; 
Stream imgstream = await client.GetStreamAsync(picloc).ConfigureAwait(false); 
Bitmap blah2 = new Bitmap(imgstream); 
BMPReadyEventArgs args = new BMPReadyEventArgs(); 
args.BMP = blah2; 
BitmapReady(this, args); 

该应用通过所有的代码运行和冻结了该请求。如果我关闭ConfigureAwait项,await会将控制权交还给UI代码,它将到达所述代码的末尾,冻结几秒钟然后加载图像。

有了configureawait(false),它会加载图像然后冻结。我认为我从请求中获得的流立即开始,所以如果它不需要等待上下文(?)它本质上同步运行。说实话,我仍然不明白configureawait实际上做了什么,或者人们谈论的上下文实际上意味着什么,但是这种行为让我认为UI冻结与代码的异步性质无关。

我看不到调试器跳过到F11(虽然这似乎有一些缺点与异步代码一起使用时)跳到一个意想不到的地方,它确实似乎只是到达代码的末尾并冻结几秒钟。

这让我想起了几个问题。

当达到代码结束时,UI是否会始终冻结,如果需要,我是否需要制作某种UI刷新代码?

而且,或者更nebulously,

有没有跟我说可能会造成这个冻结异步执行的问题吗?

编辑:Complete方法:

public async void DownloadJPG() 
    { 
     string picloc = "[redacted]"; 
     Stream imgstream = await client.GetStreamAsync(picloc).ConfigureAwait(false); 
     Bitmap blah2 = new Bitmap(imgstream); 
     BMPReadyEventArgs args = new BMPReadyEventArgs(); 
     args.BMP = blah2; 
     BitmapReady(this, args); 
    } 

private async void HoldingPattern() 
    { 
     textBox1.Text = wsmanager.passer; 
     connector.BitmapReady += (sender, e) => 
      pictureBox1.Image = e.BMP; 

     connector.DownloadJPG(); 
    } 

EDIT2称为:事件处理程序:

public event EventHandler<BMPReadyEventArgs> BitmapReady; 

BMPReadyEventArgs

class BMPReadyEventArgs:EventArgs 
{ 
    public Bitmap BMP {get;set;} 
} 
+0

请出示完整的方法和你如何调用它 –

+0

我不认为你已经显示出足够的代码为任何人提供帮助。例如,对“BitmapReady”的调用似乎引发了一个事件,但是您没有显示事件处理程序或该事件处理程序的位置。如果它在UI线程上运行,是否会成为您的冻结UI的原因?如果是这样,它是否也需要异步? –

+0

但引发'BitmapReady'处理程序时运行的代码在哪里(即用户代码)? –

回答

0

你的做法是办法

public async Task<Image> DownloadJPGAsync() 
{ 
    string picloc = "[redacted]"; 
    Stream imgstream = await client.GetStreamAsync(picloc).ConfigureAwait(false); 
    Bitmap blah2 = new Bitmap(imgstream); 
    return blah2; 
} 

从一个异步事件处理程序现在复杂

public async void Button1_Click() 
{ 
    var image = await connector.DownloadJPGAsync(); 
    pictureBox1.Image = image; 
} 
+0

该任务将从相机获取图像并将其转换为位图,但在返回之前停止。我不确定它为什么不返回位图,但我离题了。即使它工作,这不是我想要如何构建我的应用程序,因为我想处理从UI中分开获取位图(我知道我要求我的webclient处理程序从UI中获取它,但这将是改变了道路)。即使我真的想直接在我的UI线程中调用它,正如我在原始帖子的评论中提到的那样,在UI线程中等待可能不是最好的,因为它会在等待时冻结UI。 –

+0

对不起,我只是忘了将[redacted]替换为实际路径。该任务有效,但确实存在冻结UI线程的问题。这似乎是由于现在在UI线程中等待,而不是未知。我会尝试将任务调用转移到它所属的位置并回报。 –

+0

“在UI线程中等待”有**不会阻止** UIThread!你确定在GetStreamAsync(...)后面有ConfigureAwait(false)吗?否则,位图的创建将在UIThread上发生,创建将需要一些时间 –