C#字符串函数不返回值
我对这个函数有问题C#字符串函数不返回值,c#,C#,我对这个函数有问题 public static string artnetReceiver() { string dataout; List<string> dmxString = new List<string>(); byte[] _dmxData = new byte[511]; artnet.NewPacket += (object sender, ArtNet.Sockets.NewPacketEventArgs<ArtN
public static string artnetReceiver()
{
string dataout;
List<string> dmxString = new List<string>();
byte[] _dmxData = new byte[511];
artnet.NewPacket += (object sender, ArtNet.Sockets.NewPacketEventArgs<ArtNet.Packets.ArtNetPacket> e) =>
{
if (e.Packet.OpCode == ArtNet.Enums.ArtNetOpCodes.Dmx)
{
var packet = e.Packet as ArtNet.Packets.ArtNetDmxPacket;
Console.Clear();
if (packet.DmxData != _dmxData)
{
for (var i = 0; i < packet.DmxData.Length; i++)
{
if (packet.DmxData[i] != 0)
{
}
int temp = i + 1;
string chanNum = temp.ToString();
string chanValue = packet.DmxData[i].ToString();
dmxString.Add(chanNum + "-" + chanValue);
};
//dmx stuff
dataout = string.Join(",", dmxString.ToArray());
dmxOut = dataout;
//Console.WriteLine(dataout);//works here
_dmxData = packet.DmxData;
}
}
};
return dataout; // doesn't work
}
好的,我现在正在努力解决的问题实际上是稍后在我的代码调用中,比如说
artnetReceiver()
,当它运行时,它会返回字符串值,这样我就可以将它导出为数据包字符串,比如mstrResponse=“Data:+artnetReceiver()代码>这是方法中的事件处理程序,它与方法调用异步运行。
不能期望在事件句柄中返回变量集
将值存储在全局范围中的其他位置,或使用回调操作等返回值
操作的示例用法
publicstaticvoidanotherfunction()
{
ArtnetReceiver((val)=>
{
//使用返回的值进行操作
});
}
公共静态无效ArtnetReceiver(操作回调)
{
artnet.NewPacket+=(对象发送方,artnet.Sockets.NewPacketEventArgs e)=>
{
//有些事情正在发生。。。
var dataout=价值;
回调(数据输出);
};
}
这是方法中的事件处理程序,它与方法调用异步运行。
不能期望在事件句柄中返回变量集
将值存储在全局范围中的其他位置,或使用回调操作等返回值
操作的示例用法
publicstaticvoidanotherfunction()
{
ArtnetReceiver((val)=>
{
//使用返回的值进行操作
});
}
公共静态无效ArtnetReceiver(操作回调)
{
artnet.NewPacket+=(对象发送方,artnet.Sockets.NewPacketEventArgs e)=>
{
//有些事情正在发生。。。
var dataout=价值;
回调(数据输出);
};
}
冒着与MichaC的答案基本重复的风险,下面是我的解释,说明为什么您会观察到这种行为,并提供一个可能更简单的解决方案
此代码
artnet.NewPacket += (object sender, ArtNet.Sockets.NewPacketEventArgs<ArtNet.Packets.ArtNetPacket> e) =>{
//code omitted
}
事件处理程序是
//note the return type - it's void!
public void OnArtNet_NewPacket(object sender, ArtNet.Sockets.NewPacketEventArgs<ArtNet.Packets.ArtNetPacket> e)
{
string dataout; //included here so the sample will compile
if (e.Packet.OpCode == ArtNet.Enums.ArtNetOpCodes.Dmx)
{
var packet = e.Packet as ArtNet.Packets.ArtNetDmxPacket;
Console.Clear();
if (packet.DmxData != _dmxData)
{
for (var i = 0; i < packet.DmxData.Length; i++)
{
if (packet.DmxData[i] != 0)
{
}
int temp = i + 1;
string chanNum = temp.ToString();
string chanValue = packet.DmxData[i].ToString();
dmxString.Add(chanNum + "-" + chanValue);
};
//dmx stuff
dataout = string.Join(",", dmxString.ToArray());
dmxOut = dataout;
//Console.WriteLine(dataout);//works here
_dmxData = packet.DmxData;
}
}
}
注意:ProcessDataOut方法不能有返回类型(当然,它可以
但这是毫无意义的,因为那里没有任何东西可以接收
返回值)。因此,无论您需要对dataout做什么,您都可以
需要在ProcessDataOut方法中执行此操作。这就是为什么
异步/事件驱动代码工作:)
然而,更优雅(更灵活)的解决方案是使用回调委托(Action或Func),正如MichaC的回答中所指出的,但同样的概念也适用;此委托不能返回任何内容,必须执行您试图实现的任何流程的“下一步”
这意味着您可能需要反转应用程序逻辑;也就是说,与其让某个东西在“外部”等待artnetReceiver
返回某个东西(它永远不会返回),您需要将该东西移动到artnetReceiver的ProcessDataOut
方法中。冒着与MichaC的答案基本重复的风险,下面是我对为什么你会观察到这种行为的解释,可能有一个更简单的解决方案
此代码
artnet.NewPacket += (object sender, ArtNet.Sockets.NewPacketEventArgs<ArtNet.Packets.ArtNetPacket> e) =>{
//code omitted
}
事件处理程序是
//note the return type - it's void!
public void OnArtNet_NewPacket(object sender, ArtNet.Sockets.NewPacketEventArgs<ArtNet.Packets.ArtNetPacket> e)
{
string dataout; //included here so the sample will compile
if (e.Packet.OpCode == ArtNet.Enums.ArtNetOpCodes.Dmx)
{
var packet = e.Packet as ArtNet.Packets.ArtNetDmxPacket;
Console.Clear();
if (packet.DmxData != _dmxData)
{
for (var i = 0; i < packet.DmxData.Length; i++)
{
if (packet.DmxData[i] != 0)
{
}
int temp = i + 1;
string chanNum = temp.ToString();
string chanValue = packet.DmxData[i].ToString();
dmxString.Add(chanNum + "-" + chanValue);
};
//dmx stuff
dataout = string.Join(",", dmxString.ToArray());
dmxOut = dataout;
//Console.WriteLine(dataout);//works here
_dmxData = packet.DmxData;
}
}
}
注意:ProcessDataOut方法不能有返回类型(当然,它可以
但这是毫无意义的,因为那里没有任何东西可以接收
返回值)。因此,无论您需要对dataout做什么,您都可以
需要在ProcessDataOut方法中执行此操作。这就是为什么
异步/事件驱动代码工作:)
然而,更优雅(更灵活)的解决方案是使用回调委托(Action或Func),正如MichaC的回答中所指出的,但同样的概念也适用;此委托不能返回任何内容,必须执行您试图实现的任何流程的“下一步”
这意味着您可能需要反转应用程序逻辑;也就是说,与其让某个东西在“外面”等待artnetReceiver
返回某个东西(它永远不会返回)您需要在artnetReceiver的ProcessDataOut
方法中移动这些内容。旁注:除非您使用的是旧版本的.Net,否则请改用async
/Wait
——这似乎更符合您对异步代码应该如何运行的预期。旁注:除非您使用的是旧版本的.Netasync
/await
相反-它似乎更符合您对异步代码行为的期望。那么,我该如何做到这一点,然后使其成为命名空间中主类之后的全局范围呢?很抱歉,我对C比较陌生,全局范围通常非常糟糕,因为您不知道何时设置或更改变量。我会说你必须颠倒你的呼叫链。返回字符串后执行的任何操作都必须在调用事件并设置变量后运行。因此,您可能必须坚持回调,并在事件句柄中调用Func to artnetReceiver。我很清楚,我在这里尝试做我以前在C#中没有做过的高级事情。如果你能用我在OP中提供的代码演示Func的正确使用,那就太棒了。我已经为此挣扎了大约3个小时,最后放弃了,并发布到了stack。因此,我按照您现在建议的那样在代码中执行了回调部分,我遇到了返回valpublic static void getDMXPackets(){artnetReceiver((val)=>{return val;});}
这不起作用我遇到了一个关于匿名函数或类似的错误。这不起作用;)你必须将你的逻辑放入回调体中。那么我该怎么做,然后让它在我的命名空间中的主类之后成为全局作用域呢?很抱歉,我对C比较陌生,全局作用域通常是prett很糟糕,因为你
//note the return type - it's void!
public void OnArtNet_NewPacket(object sender, ArtNet.Sockets.NewPacketEventArgs<ArtNet.Packets.ArtNetPacket> e)
{
string dataout; //included here so the sample will compile
if (e.Packet.OpCode == ArtNet.Enums.ArtNetOpCodes.Dmx)
{
var packet = e.Packet as ArtNet.Packets.ArtNetDmxPacket;
Console.Clear();
if (packet.DmxData != _dmxData)
{
for (var i = 0; i < packet.DmxData.Length; i++)
{
if (packet.DmxData[i] != 0)
{
}
int temp = i + 1;
string chanNum = temp.ToString();
string chanValue = packet.DmxData[i].ToString();
dmxString.Add(chanNum + "-" + chanValue);
};
//dmx stuff
dataout = string.Join(",", dmxString.ToArray());
dmxOut = dataout;
//Console.WriteLine(dataout);//works here
_dmxData = packet.DmxData;
}
}
}
_dmxData = packet.DmxData;
ProcessDataOut(dataout);
}