我的问题似乎有些奇怪,但是使用MVVM模式创建WPF套接字客户端的最佳方法是什么?
现在在我的ViewModel上,我创建一个线程,该线程尝试在while循环中连接到服务器,并在连接后等待连接,它从服务器获取数据。
有没有更好的方法可以做到这一点,这样我就不必在不阻塞主UI线程的情况下使用新的Thread了?
相关的ViewModel代码:
serverInfo.ClientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
serverInfo.PORT = 1488;
//Initialize LeecherList
p_LeecherList = new ObservableCollection<LeecherDetails>();
//Subscribe to CollectionChanged Event
p_LeecherList.CollectionChanged += OnLeecherListchanged;
AccountsInfo = JsonConvert.DeserializeObject<RootObject>(File.ReadAllText(Path.Combine(Directory.GetCurrentDirectory(), "Accounts.json")));
foreach (var x in AccountsInfo.Accounts)
{
p_LeecherList.Add(new LeecherDetails("N/A", x.Email, x.Password, false, "Collapsed"));
}
base.RaisePropertyChangedEvent("LeecherList");
Thread ConnectionLoop = new Thread(() =>
{
ServerStatus = "Connecting...";
while (true)
{
if (!serverInfo.HasConnectedOnce && !serverInfo.ClientSocket.Connected)
{
try
{
serverInfo.ClientSocket.Connect(IPAddress.Loopback, serverInfo.PORT);
}
catch (SocketException)
{
}
}
else if (serverInfo.ClientSocket.Connected && !serverInfo.HasConnectedOnce)
{
serverInfo.HasConnectedOnce = true;
ServerStatus = "Online";
break;
}
}
while (true)
{
try
{
var buffer = new byte[8000];
int received = serverInfo.ClientSocket.Receive(buffer, SocketFlags.None);
if (received == 0) return;
var data = new byte[received];
Array.Copy(buffer, data, received);
var st = helper.ByteToObject(data);
if (st is string info)
{
}
else
{
}
}
catch
{
continue;
}
}
});
ConnectionLoop.IsBackground = true;
ConnectionLoop.Start();
提前致谢。
最佳答案
出色地;您应该将此逻辑放在一种Service
中。
例子:
因此,您可以创建一个这样的服务,注意:启动,停止和传递数据的事件。
基本思想是将更多的业务(如通信逻辑)移到单独的服务中,这样,如果您以后需要更改它,则该逻辑将更加孤立,并且不会与您的 View 模型混合。
//note, you could encapsulate functionality in an interface, e.g.: IService
public class SomeService
{
public event EventHandler<YourEventData> OnSomethingHappening;
public SomeService(some parameters)
{
//some init procedure
}
public void Stop()
{
//your stop logic
}
public void Start()
{
//your start logic
}
private void Runner() //this might run on a seperate thread
{
while(running)
{
if (somecondition)
{
OnSomethingHappening?.Invoke(this, new YourEventData());
}
}
}
public string SomeFooPropertyToGetOrSetData {get;set;}
}
在应用程序中的某个位置(可能是在启动时)创建其中之一。
然后将其传递给您的viewmodel,也许通过构造函数。在这种情况下,您的 View 模型将如下所示:
public class YourViewModel
{
private SomeService_service;
public YourViewModel(SomeServiceyourService)
{
_service = yourService;
_service.OnSomethingHappening += (s,a) =>
{
//event handling
};
}
}
//etc.
关于c# - WPF套接字客户端结构,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/51919210/