我尝试了其他帖子中的许多建议,但没有任何帮助。我对 .asp.net Web 应用程序还很陌生。我相信闪烁是由 HttpClient->PostAsync
调用引起的,因为当我增加 Thread.Sleep(100)
时,它似乎不太经常发生。此外,当我启动另一个网页(即在同一个 TCP 端口上创建一个 HttpClient)时,它似乎更频繁地发生。我将所有内容都放在更新面板中,并包含一个计时器作为 asyncpostbacktrigger
,以便在每次回发时使用新图像数据更新此图像。我想我在下面包含了所有相关代码:
CSS/HTML:
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<style type="text/css">
body {
background-color: black;
margin: 0;
padding: 0;
}
#Image1 {
position: fixed;
width: 100%;
height: 90.0vh;
left: 0px;
right: 0px;
top: 5.0vh;
bottom: 0px;
object-fit: contain;
z-index: -1;
}
</style>
</head>
<body onload="'">
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server" EnablePageMethods="True" />
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
<Triggers>
<asp:AsyncPostBackTrigger ControlID="Timer1" EventName="Tick" />
</Triggers>
<ContentTemplate>
<asp:Image ID="Image1" runat="server" />
</ContentTemplate>
</asp:UpdatePanel>
<asp:Timer ID="Timer1" OnTick="Timer_tick" Interval="100" runat="server">
</asp:Timer>
</form>
</body>
</html>
C# 后端:
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct IMAGE_TYPE
{
public int count; //Running counter.
public int dim; //The dimension of x and y (square).
public int bufsize; //The number of bytes used for RGB data in data_image.
double angle;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 5000)]
public byte[] future_unused;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2048*2048)]
public byte[] data_image;
}
private static int _tcpPort = 44338;
private static readonly HttpClient _client = new HttpClient();
private static readonly Bitmap _image = new Bitmap(2048, 2048, PixelFormat.Format32bppRgb);
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
if (!_isPageLoaded)
{
//No need to process this code besides from the initial loading of the webpage.
//This code will be ignored when webpage is refreshed or accessed by more than one user.
_isPageLoaded = true;
LocalImageBuf = new IMAGE_TYPE
{
data_image = new byte[2048*2048],
future_unused = new byte[5000],
};
string baseAddress = string.Format("http://localhost:{0}/", _tcpPort);
_client.BaseAddress = new Uri(baseAddress);
Thread getImageThread = new Thread(GetImage);
getImageThread.Start();
}
}
}
private async void GetImage()
{
while (true)
{
try
{
string img = "$IMG,0";
byte[] data = Encoding.ASCII.GetBytes(img);
ByteArrayContent array = new ByteArrayContent(data);
array.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
using (HttpResponseMessage response = await _client.PostAsync("Image", array))
{
using (HttpContent content = response.Content)
{
byte[] imageData = await content.ReadAsByteArrayAsync();
//Image data is at index 5020 of the returned struct.
Array.Copy(imageData, 5020, LocalImageBuf, 0, LocalImageBuf.Length);
}
}
PrepareData();
//Sleep for 100ms.
Thread.Sleep(100);
}
catch (Exception e)
{
System.Diagnostics.Debug.WriteLine(e.Message);
//Sleep for 1s.
Thread.Sleep(1000);
}
}
}
private void PrepareData()
{
lock (LockClass.DrawLock)
{
Rectangle rect = new Rectangle(0, 0, _image.Width, _image.Height);
BitmapData bitmapData = _image.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
IntPtr pixels1 = bitmapData.Scan0;
int stride = bitmapData.Stride;
unsafe
{
int* pt1 = (int*)pixels1.ToPointer();
//Begin at the first byte of the output buffer.
fixed (byte* img1 = &LocalImageBuf.data_image[0])
{
byte* ppt1 = img1;
for (int y = 0; y < _image.Height; y++)
{
for (int x = 0; x < _image.Width; x++, pt1++, ppt1++)
{
*pt1 = *ppt1;
}
}
}
}
_image.UnlockBits(bitmapData);
}
}
protected void Timer_tick(object sender, EventArgs e)
{
//Causes a postback trigger for our echo buffer to be saved to the client image.
lock (LockClass.DrawLock)
{
using (var ms = new MemoryStream())
{
_image.Save(ms, ImageFormat.Png);
Image1.ImageUrl = "data:image;base64," + Convert.ToBase64String(ms.ToArray());
}
}
}
public static class LockClass
{
public static object DrawLock = new object();
}
这是正在发生的事情的一个例子。我希望黄色圆圈始终显示(对于此示例,始终通过 PostAsync 返回相同的数据)。但它一直闪烁到数据空白的地方,可能每隔 0.5-3 秒(非常随机)。