我对Asynchronous很新,我理解一些一般概念,但我似乎无法解决几个问题。
我有以下ReceiveCallback:
public static void ReceiveCallback(IAsyncResult AR)
{
Socket CurrentSocket = (Socket)AR.AsyncState;
int DataReceived = 0;
try
{
DataReceived = CurrentSocket.EndReceive(AR);
}
catch (SocketException)
{
CurrentSocket.Close();
return;
}
byte[] receivedBuffer = new byte[DataReceived];
Array.Copy(Buffer, receivedBuffer, DataReceived);
strReceived = Encoding.ASCII.GetString(receivedBuffer); // We are saving the latest receivedBuffer in a string.
new MainWindow().Process(); // We are accessing a function in the MainWindow class
receiveDone.Set();
CurrentSocket.BeginReceive(Buffer, 0, BufferSize, SocketFlags.None, ReceiveCallback, CurrentSocket);
}
这是“Process()”代码:
public void Process()
{
lblReceived.Text = ClientSocket.strReceived; // Trying to set what we received in a label..
}
在线:“new MainWindow()。Process();”, 我收到以下异常:“附加信息:调用线程必须是STA,因为许多UI组件都需要这个。” 我已经搜索过,并理解为什么它给了我例外,但是有些代码对我不起作用。
标签没有改变,我知道我正在创建一个MainWindow的新实例,这就是为什么没有显示,但我正在寻找如何通过使用新实例来改变标签的例子
答案 0 :(得分:0)
不幸的是,如果没有a good, minimal, complete code example,就无法了解有关您问题的足够背景信息,无法提供准确答案。
但可以做一些一般性的观察:
因此,只是因为你无法访问类的某个实例成员(比如这里的Process()
方法)而创建一个全新的类实例总是错误的。
相反,您需要提供对具有您需要访问权限的状态的已存在实例的访问权限。
ReceiveCallback()
方法实际上是在MainWindow
类中声明的。如果这个猜测是正确的,那么对代码最明显的修复就是简单地使ReceiveCallback()
方法非static
。即从方法声明中删除static
。完成后,您只需直接致电Process()
,而不是先创建MainWindow
的新实例。现在,您可能(或可能不会)发现提供方法作为原始I / O操作的参数需要修复。同样,由于您没有提供良好的代码示例,因此无法确定是否或如何执行此操作。但我提到它只是为了让你不要简单地放弃这个想法,如果你从声明中删除static
后它就不起作用。
当然,我的猜测可能是错的。在这种情况下,一个选项是提供对MainWindow
实例的引用作为I / O操作的状态对象。再说一次,如果没有一个好的代码示例,这究竟是多么有效,但基本的想法是将它作为Socket.BeginReceive()
方法的最后一个参数(任何重载)传递,然后从{{{您IAsyncResult.AsyncState
方法中的1}}属性。
注意:以上内容仅用于解决您遇到的特定异常,因为创建新的ReceiveCallback()
实例只是保证是错误的做法。由于I / O操作最有可能在UI线程之外完成,因此您仍然遇到与处理该问题相关的问题(例如,需要在访问UI本身的代码上调用MainWindow
)。但是一步一步。让我们先解决眼前的问题,然后继续下一步。
如果以上都不是有用的,那么请修正您的问题,以便它包含一个很好的代码示例,可以提供实际,准确的答案。